resolver: update targets based on direct dependencies.
authorKrisztian Litkey <kli@iki.fi>
Sat, 14 Sep 2013 06:25:36 +0000 (09:25 +0300)
committerKrisztian Litkey <kli@iki.fi>
Wed, 18 Sep 2013 13:12:30 +0000 (16:12 +0300)
Don't run unconditionally the actions of a target if any
of the facts in the transitive closure of the dependencies
have changed. Instead always check the immediate dependencies
and run the actions only if some of those have changed.

src/resolver/resolver-types.h
src/resolver/resolver.c
src/resolver/target-sorter.c
src/resolver/target.c
src/resolver/target.h

index bd5012b..e1e3f70 100644 (file)
@@ -52,6 +52,8 @@ struct target_s {
     int              ndepend;            /* number of dependencies */
     int             *update_facts;       /* facts to check when updating */
     int             *update_targets;     /* targets to check when updating */
+    int             *directs;            /* direct dependencies */
+    int              ndirect;            /* number of direct dependencies */
     uint32_t        *fact_stamps;        /* stamps of facts at last update */
     mrp_scriptlet_t *script;             /* update script if any, or NULL */
     int              prepared : 1;       /* ready for resolution */
index 5dd3c7e..5087e8c 100644 (file)
@@ -279,6 +279,7 @@ int mrp_resolver_update_targetv(mrp_resolver_t *r, const char *target,
 
 void mrp_resolver_dump_targets(mrp_resolver_t *r, FILE *fp)
 {
+    fprintf(fp, "%d target%s\n", r->ntarget, r->ntarget != 1 ? "s" : "");
     dump_targets(r, fp);
 }
 
@@ -288,10 +289,10 @@ void mrp_resolver_dump_facts(mrp_resolver_t *r, FILE *fp)
     int     i;
     fact_t *f;
 
-    fprintf(fp, "%d facts\n", r->nfact);
+    fprintf(fp, "%d fact%s\n", r->nfact, r->nfact != 1 ? "s" : "");
     for (i = 0; i < r->nfact; i++) {
         f = r->facts + i;
-        fprintf(fp, "  #%d: %s\n", i, f->name);
+        fprintf(fp, "  #%d: %s (@%u)\n", i, f->name, fact_stamp(r, i));
     }
 }
 
index 3efd397..0d3978f 100644 (file)
@@ -36,6 +36,8 @@
 #include "scanner.h"
 #include "resolver.h"
 #include "resolver-types.h"
+#include "fact.h"
+#include "target.h"
 #include "target-sorter.h"
 
 
@@ -74,9 +76,11 @@ int sort_targets(mrp_resolver_t *r)
             mrp_free(t->update_targets);
             mrp_free(t->update_facts);
             mrp_free(t->fact_stamps);
+            mrp_free(t->directs);
             t->update_targets = NULL;
             t->update_facts   = NULL;
             t->fact_stamps    = NULL;
+            t->ndirect        = 0;
         }
 
         for (i = 0; i < r->ntarget; i++) {
@@ -462,6 +466,41 @@ static int sort_graph(graph_t *g, int target_idx)
             else
                 goto fail;
         }
+
+        target->ndirect = 0;
+        target->directs = mrp_allocz_array(int, target->ndepend);
+
+        if (target->ndepend == 0 || target->directs != NULL) {
+            fact_t   *f;
+            target_t *t;
+
+            for (i = 0; i < target->ndepend; i++) {
+                if (*target->depends[i] != '$')
+                    continue;
+
+                f = lookup_fact(g->r, target->depends[i]);
+
+                if (f != NULL)
+                    target->directs[target->ndirect++] = f - g->r->facts;
+                else
+                    target->directs[target->ndirect++] = -1;
+            }
+
+            for (i = 0; i < target->ndepend; i++) {
+                if (*target->depends[i] == '$')
+                    continue;
+
+                t = lookup_target(g->r, target->depends[i]);
+
+                if (t != NULL)
+                    target->directs[target->ndirect++] = g->r->nfact +
+                        t - g->r->targets;
+                else
+                    target->directs[target->ndirect++] = -1;
+            }
+        }
+        else
+            goto fail;
     }
 
     que_cleanup(&L);
index 749b267..8099159 100644 (file)
@@ -45,6 +45,7 @@
 #include "target.h"
 
 
+
 int create_targets(mrp_resolver_t *r, yy_res_parser_t *parser)
 {
     mrp_list_hook_t *lp, *ln;
@@ -90,6 +91,7 @@ static void purge_target(target_t *t)
     mrp_free(t->update_facts);
     mrp_free(t->update_targets);
     mrp_free(t->fact_stamps);
+    mrp_free(t->directs);
 
     for (i = 0; i < t->ndepend; i++)
         mrp_free(t->depends[i]);
@@ -291,10 +293,21 @@ static int older_than_facts(mrp_resolver_t *r, target_t *t)
     if (t->update_facts == NULL)
         return TRUE;
     else {
+#ifdef CHECK_TRANSITIVE_CLOSURE_OF_FACTS
         for (i = 0; (id = t->update_facts[i]) >= 0; i++) {
             if (fact_stamp(r, id) > t->fact_stamps[i])
                 return TRUE;
         }
+#else
+        for (i = 0; i < t->ndirect; i++) {
+            id = t->directs[i];
+
+            if (id < r->nfact) {
+                if (fact_stamp(r, id) > t->fact_stamps[i])
+                    return TRUE;
+            }
+        }
+#endif
     }
 
     return FALSE;
@@ -383,6 +396,8 @@ static void update_target_stamps(mrp_resolver_t *r, target_t *t)
     if (t->update_facts != NULL)
         for (i = 0; (id = t->update_facts[i]) >= 0; i++)
             t->fact_stamps[i] = fact_stamp(r, id);
+
+    t->stamp = r->stamp;
 }
 
 
@@ -402,6 +417,8 @@ static int update_target(mrp_resolver_t *r, target_t *t)
             return -EINVAL;
     }
 
+    r->stamp = r->stamp + 1;
+
     level = r->level++;
     emit_resolver_event(RESOLVER_UPDATE_STARTED, t->name, level);
 
@@ -461,17 +478,28 @@ static int update_target(mrp_resolver_t *r, target_t *t)
 }
 
 
-int update_target_by_name(mrp_resolver_t *r, const char *name)
+target_t *lookup_target(mrp_resolver_t *r, const char *name)
 {
-    target_t *t;
+   target_t *t;
     int       i;
 
     for (i = 0, t = r->targets; i < r->ntarget; i++, t++) {
         if (!strcmp(t->name, name))
-            return update_target(r, t);
+            return t;
     }
 
-    return FALSE;
+    return NULL;
+}
+
+
+int update_target_by_name(mrp_resolver_t *r, const char *name)
+{
+    target_t *t = lookup_target(r, name);
+
+    if (t != NULL)
+        return update_target(r, t);
+    else
+        return FALSE;
 }
 
 
@@ -526,10 +554,9 @@ void dump_targets(mrp_resolver_t *r, FILE *fp)
     int       i, j, idx;
     target_t *t;
 
-    fprintf(fp, "%d targets\n", r->ntarget);
     for (i = 0; i < r->ntarget; i++) {
         t = r->targets + i;
-        fprintf(fp, "#%d: %s\n", i, t->name);
+        fprintf(fp, "#%d: %s (@%u)\n", i, t->name, t->stamp);
 
         fprintf(fp, "  dependencies:");
         if (t->depends != NULL) {
@@ -540,7 +567,8 @@ void dump_targets(mrp_resolver_t *r, FILE *fp)
             fprintf(fp, "  facts to check:");
             if (t->update_facts != NULL) {
                 for (j = 0; (idx = t->update_facts[j]) >= 0; j++)
-                    fprintf(fp, " %s", r->facts[idx].name);
+                    fprintf(fp, " %s (@%u)", r->facts[idx].name,
+                            t->fact_stamps[j]);
                 fprintf(fp, "\n");
             }
             else
@@ -549,7 +577,22 @@ void dump_targets(mrp_resolver_t *r, FILE *fp)
             fprintf(fp, "  target update order:");
             if (t->update_targets != NULL) {
                 for (j = 0; (idx = t->update_targets[j]) >= 0; j++)
-                    fprintf(fp, " %s", r->targets[idx].name);
+                    fprintf(fp, " %s (@%u)", r->targets[idx].name,
+                            r->targets[idx].stamp);
+                fprintf(fp, "\n");
+            }
+            else
+                fprintf(fp, "<none>\n");
+
+            fprintf(fp, "  direct dependencies:");
+            if (t->ndirect > 0) {
+                for (j = 0; j < t->ndirect; j++) {
+                    idx = t->directs[j];
+                    if (idx < r->nfact)
+                        fprintf(fp, " %s", r->facts[idx].name);
+                    else
+                        fprintf(fp, " %s", r->targets[idx-r->nfact].name);
+                }
                 fprintf(fp, "\n");
             }
             else
@@ -559,10 +602,18 @@ void dump_targets(mrp_resolver_t *r, FILE *fp)
             fprintf(fp, " <none>\n");
 
         if (t->script != NULL) {
-            fprintf(fp, "  update script (%s):\n",
-                    t->script->interpreter->name);
-            fprintf(fp, "%s", t->script->source);
-            fprintf(fp, "  end script\n");
+            if (t->script->source != NULL) {
+                fprintf(fp, "  update script (%s):\n",
+                        t->script->interpreter->name);
+                fprintf(fp, "%s", t->script->source);
+                fprintf(fp, "  end script\n");
+            }
+            else if (t->script->data != NULL) {
+                fprintf(fp, "  precompiled update (%s):\n",
+                        t->script->interpreter->name);
+                fprintf(fp, "    %p\n", t->script->data);
+                fprintf(fp, "  end script\n");
+            }
         }
         else
             fprintf(fp, "  no update script\n");
index 1b53ab9..aeff4fc 100644 (file)
@@ -47,6 +47,7 @@ int update_target_by_name(mrp_resolver_t *r, const char *name);
 int update_target_by_id(mrp_resolver_t *r, int id);
 int schedule_target_autoupdate(mrp_resolver_t *r);
 
+target_t *lookup_target(mrp_resolver_t *s, const char *name);
 void dump_targets(mrp_resolver_t *r, FILE *fp);
 
 #endif /* __MURPHY_RESOLVER_TARGET_H__ */