Speed up export cost calculation in assemble_dist_paths()
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 19 Feb 2011 07:21:33 +0000 (08:21 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Mon, 11 Apr 2011 20:29:13 +0000 (22:29 +0200)
Import and export paths enter the same sectors, except for the last
one.  Compute export cost from import cost instead of reverting the
import path.  Do it in dodistribute(), so that we need to store only
import costs.

src/lib/update/distribute.c
src/lib/update/finish.c

index ddc88bdd5a1b3efffb8145e84979e77d97936b05..7e94812cd393e306ef11ec3ada2dcc579795057f 100644 (file)
@@ -30,6 +30,7 @@
  *  Known contributors to this file:
  *     Dave Pare, 1986
  *     Steve McClure, 1998
+ *     Markus Armbruster, 2004-2011
  */
 
 #include <config.h>
@@ -51,8 +52,9 @@
 #define IMPORT_BONUS 10.0
 
 int
-dodistribute(struct sctstr *sp, int imex, double path_cost)
+dodistribute(struct sctstr *sp, int imex, double import_cost)
 {
+    double path_cost, dcc;
     struct ichrstr *ip;
     struct sctstr *dist;
     int amt;
@@ -71,16 +73,23 @@ dodistribute(struct sctstr *sp, int imex, double path_cost)
     if ((sp->sct_dist_x == sp->sct_x) && (sp->sct_dist_y == sp->sct_y))
        return 0;
 
-    if (path_cost < 0.0) {
-       if (sp->sct_own != 0) {
-           if (imex == EXPORT) /* only want this once */
+    if (imex == IMPORT && import_cost < 0.0)
+       return 0;
+
+    dist = getsectp(sp->sct_dist_x, sp->sct_dist_y);
+    if (imex == IMPORT)
+       path_cost = import_cost;
+    else {
+       dcc = sector_mcost(dist, MOB_MOVE);
+       if (import_cost < 0.0 || dcc < 0.0) {
+           if (sp->sct_own != 0)
                wu(0, sp->sct_own, "No path to dist sector for %s\n",
                   ownxy(sp));
+           return 0;
        }
-       return 0;
+       path_cost = import_cost - sector_mcost(sp, MOB_MOVE) + dcc;
     }
 
-    dist = getsectp(sp->sct_dist_x, sp->sct_dist_y);
     dist_packing = dist->sct_effic >= 60 ? dchr[dist->sct_type].d_pkg : IPKG;
     sect_packing = sp->sct_effic   >= 60 ? dchr[sp->sct_type].d_pkg : IPKG;
 
index 1544f45da24c4361f311bb49dca31e6b39370ed7..528fce7abc324c17525c2fed11857b53354e8b2f 100644 (file)
@@ -31,6 +31,7 @@
  *     Dave Pare, 1986
  *     Thomas Ruschak, 1993
  *     Steve McClure, 1998
+ *     Markus Armbruster, 2004-2011
  */
 
 #include <config.h>
 #include "path.h"
 #include "update.h"
 
-/* Used for building up distribution info */
-struct distinfo {
-    double imcost;             /* import cost */
-    double excost;             /* export cost */
-};
-
-/* This is our global buffer of distribution pointers.  Note that
- * We only malloc this once, and never again (until reboot time
- * of course :) ) We do clear it each and every time. */
-static struct distinfo *g_distptrs;
-
-static void assemble_dist_paths(struct distinfo *distptrs);
-static char *ReversePath(char *path);
+static void assemble_dist_paths(double *);
 
 void
 finish_sects(int etu)
 {
+    static double *import_cost;
     struct sctstr *sp;
     struct natstr *np;
     int n;
     struct rusage rus1, rus2;
-    struct distinfo *infptr;
 
-    if (g_distptrs == NULL) {
+    if (import_cost == NULL) {
        logerror("First update since reboot, allocating buffer\n");
-       /* Allocate the information buffer */
-       g_distptrs = malloc(WORLD_SZ() * sizeof(*g_distptrs));
-       if (g_distptrs == NULL) {
+       import_cost = malloc(WORLD_SZ() * sizeof(*import_cost));
+       if (import_cost == NULL) {
            logerror("malloc failed in finish_sects.\n");
            return;
        }
     }
 
-    /* Wipe it clean */
-    memset(g_distptrs, 0, WORLD_SZ() * sizeof(*g_distptrs));
+    memset(import_cost, 0, WORLD_SZ() * sizeof(*import_cost));
 
     logerror("delivering...\n");
     /* Do deliveries */
@@ -98,7 +85,7 @@ finish_sects(int etu)
     bp_enable_cachepath();
 
     /* Now assemble the paths */
-    assemble_dist_paths(g_distptrs);
+    assemble_dist_paths(import_cost);
 
     /* Now disable the best_path cacheing */
     bp_disable_cachepath();
@@ -120,22 +107,18 @@ finish_sects(int etu)
        np = getnatp(sp->sct_own);
        if (np->nat_money < 0)
            continue;
-       /* Get the pointer */
-       infptr = &g_distptrs[sp->sct_uid];
-       dodistribute(sp, EXPORT, infptr->excost);
+       dodistribute(sp, EXPORT, import_cost[n]);
     }
     logerror("done exporting\n");
 
     logerror("importing...");
     for (n = 0; NULL != (sp = getsectid(n)); n++) {
-       /* Get the pointer (we do it first so we can free if needed) */
-       infptr = &g_distptrs[sp->sct_uid];
        if (sp->sct_type == SCT_WATER || sp->sct_own == 0)
            continue;
        np = getnatp(sp->sct_own);
        if (np->nat_money < 0)
            continue;
-       dodistribute(sp, IMPORT, infptr->imcost);
+       dodistribute(sp, IMPORT, import_cost[n]);
        sp->sct_off = 0;
     }
     logerror("done importing\n");
@@ -143,21 +126,18 @@ finish_sects(int etu)
 }
 
 static void
-assemble_dist_paths(struct distinfo *distptrs)
+assemble_dist_paths(double *import_cost)
 {
-    char *path, *p;
+    char *path;
     double d;
     struct sctstr *sp;
     struct sctstr *dist;
-    struct distinfo *infptr;
     int n;
     char buf[512];
 
     for (n = 0; NULL != (sp = getsectid(n)); n++) {
        if ((sp->sct_dist_x == sp->sct_x) && (sp->sct_dist_y == sp->sct_y))
            continue;
-       /* Set the pointer */
-       infptr = &distptrs[sp->sct_uid];
        /* now, get the dist sector */
        dist = getsectp(sp->sct_dist_x, sp->sct_dist_y);
        if (dist == NULL) {
@@ -170,45 +150,9 @@ assemble_dist_paths(struct distinfo *distptrs)
        /* Note we go from the dist center to the sector.  This gives
           us the import path for that sector. */
        path = BestDistPath(buf, dist, sp, &d);
-
-       /* Now, we have a path */
-       if (!path)
-           infptr->imcost = infptr->excost = -1.0;
-       else {
-           /* Save the import cost */
-           infptr->imcost = d;
-           /* Now, reverse the path */
-           p = ReversePath(path);
-           /* And walk the path back to the dist center to get the export
-              cost */
-           infptr->excost = pathcost(sp, p, MOB_MOVE);
-       }
-    }
-}
-
-static char *
-ReversePath(char *path)
-{
-    char *patharray = "aucdefjhigklmyopqrstbvwxnz";
-    static char new_path[512];
-    int ind;
-
-    if (path == NULL)
-       return NULL;
-
-    ind = strlen(path);
-    if (ind == 0)
-       return NULL;
-
-    if (path[ind - 1] == 'h')
-       ind--;
-
-    new_path[ind--] = '\0';
-    new_path[ind] = '\0';
-
-    while (ind >= 0) {
-       new_path[ind--] = patharray[*(path++) - 'a'];
+       if (path)
+           import_cost[n] = d;
+       else
+           import_cost[n] = -1;
     }
-
-    return new_path;
 }