[Xastir-dev] Anyone interested in trying a patch?

Jason Godfrey godfreja at gmail.com
Sat Feb 5 13:56:21 EST 2011


Thanks. That "feature" of Gmail can be annoying.

Here is the patch. (It's based off of a checkout of about a month, but with
CVS down I can't get anything newer. I'm guessing it will still apply
cleanly though.)

>From 598953258754030c27f6b1bed478c56f0e58fb77 Mon Sep 17 00:00:00 2001
From: Jason Godfrey <godfreja at gmail.com>
Date: Fri, 4 Feb 2011 21:22:16 -0600
Subject: [PATCH] Speed up dbfawk handling


diff --git a/src/awk.c b/src/awk.c
index 3e7c0c9..82df028 100644
--- a/src/awk.c
+++ b/src/awk.c
@@ -87,25 +87,6 @@
 #define min(a,b) ((a)<(b)?(a):(b))

 /*
- * Symbol table
- *
- * Symbols $0-$9 are set by the results of the pcre pattern match.
- * Other symbols are declared by the caller and bound to variables
- * in the caller's program.  Make sure they are still in scope when
- * the pattern matcher is invoked!
- *
- * This assumes a very small symbol table, so it is searched linearly.
- * No fancy hash table lookups are needed.
- * XXX YES THEY ARE!
- */
-
-#define MAXSUBS 10              /* $0 thru $9 should be plenty */
-
-
-
-
-
-/*
  * awk_new_symtab: alloc a symbol table with $0-$9 pre-declared.
  */
 awk_symtab *awk_new_symtab(void) {
@@ -122,7 +103,7 @@ awk_symtab *awk_new_symtab(void) {
     for (i = 0; i < MAXSUBS; i++) {
         sym[i][0] = i+'0';
         sym[i][1] = '\0';
-        awk_declare_sym(n,sym[i],STRING,NULL,0); /* just reserve the name
*/
+        n->binds[i] = awk_declare_sym(n,sym[i],STRING,NULL,0); /* just
reserve the name */
     }
     return n;
 }
@@ -152,7 +133,7 @@ void awk_free_symtab(awk_symtab *s) {
 /*
  * awk_declare_sym: declare a symbol and bind to storage for its value.
  */
-int awk_declare_sym(awk_symtab *this,
+awk_symbol* awk_declare_sym(awk_symtab *this,
                 const char *name,
                 enum awk_symtype type,
                 const void *val,
@@ -164,7 +145,7 @@ int awk_declare_sym(awk_symtab *this,

     if (!s) {
         fprintf(stderr, "Couldn't allocate memory in awk_declare_sym()\n");
-        return -1;
+        return NULL;
     }

     s->name = name;
@@ -179,7 +160,7 @@ int awk_declare_sym(awk_symtab *this,
     }
     this->hash[i] = s;          /* make (new) top of bucket */

-    return 0;
+    return s;
 }


@@ -526,7 +507,11 @@ void awk_eval_expr(awk_symtab *this,
                         --exprlen;
                     }
                 }
-                src = awk_find_sym(this,symname,(expr-symname));
+                if( ((expr-symname)==1) && (symname[0]>='0') &&
(symname[0]<='9'))
+                {
+    src = this->binds[symname[0]-'0'];
+                }
+                else src = awk_find_sym(this,symname,(expr-symname));
                 if (delim) {    /* gotta skip over the close delim */
                     ++expr;
                     --exprlen;
@@ -656,6 +641,7 @@ awk_rule *awk_new_rule(void) {
     if (!n)
         fprintf(stderr,"Couldn't allocate memory in awk_new_rule()\n");

+    n->hint = -1;
     return n;
 }

@@ -930,12 +916,13 @@ int awk_compile_program(awk_symtab *symtab,
awk_program *rs) {
     rs->symtbl = symtab;
     for (r = rs->head; r; r = r->next_rule) {
         if (r->ruletype == REGEXP) {
+            r->hint=-1;
             if (r->tables)
                 pcre_free((void *)r->tables);
             r->tables = pcre_maketables(); /* NLS locale parse tables */
             if (!r->re)
                 r->re = pcre_compile(r->pattern, /* the pattern */
-                                     0, /* default options */
+                                     PCRE_DOTALL, /* default options */
                                      &error, /* for error message */
                                      &erroffset, /* for error offset */
                                      r->tables); /* NLS locale character
tables */
@@ -1004,10 +991,62 @@ void awk_uncompile_program(awk_program *p) {



+
+/*
+ * awk_set_program_hints: Determine if rule only applies to hint number
+ */
+int awk_set_program_hints(awk_program *this, char *buf, int hintNum) {
+    awk_rule *r;
+    const char *error;
+    int erroffset;
+    int rc;
+    pcre *re;
+    pcre_extra *pe;
+    int patLen = strlen(buf) + 8;
+    char *pattern = (char*) malloc( patLen );
+    xastir_snprintf( pattern, patLen, "^\\^%s=", buf );
+    int ovector[3*MAXSUBS];
+#define OVECLEN (sizeof(ovector)/sizeof(ovector[0]))
+
+    re = pcre_compile(pattern, /* the pattern */
+                         PCRE_DOTALL, /* default options */
+                         &error, /* for error message */
+                         &erroffset, /* for error offset */
+                         this->head->tables); /* NLS locale character
tables */
+    if (!re) {
+        int i;
+
+        fprintf(stderr,"parse error: %s\n",pattern);
+        fprintf(stderr,"             ");
+        for (i = 0; i < erroffset; i++)
+            fputc(' ',stderr);
+        fprintf(stderr,"^\n");
+        free(pattern);
+        return -1;
+    }
+    pe = pcre_study(re, 0, &error); /* optimize the regexp */
+
+    for (r = this->head; r; r = r->next_rule) {
+        if (r->ruletype == REGEXP) {
+            rc =
pcre_exec(re,pe,r->pattern,strlen(r->pattern),0,0,ovector,OVECLEN);
+    if( rc>-1 )
+            {
+                if( r->hint >= 0 ) r->hint = -2;
+                else if( r->hint == -1 ) r->hint = hintNum;
+            }
+        }
+    }
+    pcre_free(re);
+    pcre_free(pe);
+    free(pattern);
+    return 0;
+}
+
+
 /*
  * awk_exec_program: apply the program to the given buffer
  */
-int awk_exec_program(awk_program *this, char *buf, int len) {
+int awk_exec_program(awk_program *this, char *buf, int len, int hintNum) {
     int i,rc,done = 0;
     awk_rule *r;
     int ovector[3*MAXSUBS];
@@ -1018,27 +1057,21 @@ int awk_exec_program(awk_program *this, char *buf,
int len) {

     for (r = this->head; r && !done ; r = r->next_rule) {
         if (r->ruletype == REGEXP) {
+            if( (hintNum >= -1) && (hintNum != r->hint ) ) continue;
             rc = pcre_exec(r->re,r->pe,buf,len,0,0,ovector,OVECLEN);
             /* assign values to as many of $0 thru $9 as were set */
-            /* XXX - avoid calling awk_find_sym for these known values */
             for (i = 0; rc > 0 && i < rc && i < MAXSUBS ; i++) {
-                char symname[2];
                 awk_symbol *s;

-                symname[0] = i + '0';
-                symname[1] = '\0';
-                s = awk_find_sym(this->symtbl,symname,1);
+                s = this->symtbl->binds[i];
                 s->val = &buf[ovector[2*i]];
                 s->len = ovector[2*i+1]-ovector[2*i];
             }
             /* clobber the remaining $n thru $9 */
             for (; i < MAXSUBS; i++) {
-                char symname[10];
                 awk_symbol *s;

-                symname[0] = i + '0';
-                symname[1] = '\0';
-                s = awk_find_sym(this->symtbl,symname,1);
+                s = this->symtbl->binds[i];
                 s->len = 0;
             }
             if (rc > 0) {
diff --git a/src/awk.h b/src/awk.h
index a82232f..4e21a75 100644
--- a/src/awk.h
+++ b/src/awk.h
@@ -43,8 +43,25 @@ typedef struct awk_symbol_ { /* symbol table entry */
 } awk_symbol;

 #define AWK_SYMTAB_HASH_SIZE 0xff
+
+/*
+ * Symbol table
+ *
+ * Symbols $0-$9 are set by the results of the pcre pattern match.
+ * Other symbols are declared by the caller and bound to variables
+ * in the caller's program.  Make sure they are still in scope when
+ * the pattern matcher is invoked!
+ *
+ * This assumes a very small symbol table, so it is searched linearly.
+ * No fancy hash table lookups are needed.
+ * XXX YES THEY ARE!
+ */
+
+#define MAXSUBS 10              /* $0 thru $9 should be plenty */
+
 typedef struct awk_symtab_ { /* symbol table anchor */
     awk_symbol *hash[AWK_SYMTAB_HASH_SIZE];
+    awk_symbol* binds[MAXSUBS];
 } awk_symtab;

 #define AWK_SYM_HASH(n,l) ((*n)&AWK_SYMTAB_HASH_SIZE)
@@ -68,6 +85,7 @@ typedef struct awk_rule_ {
     const char *act;            /* the program string */
     awk_action *code; /* compiled program */
     int flags; /* some flags */
+    int hint; /* Hint (column) number, or negative if not set */
 #define AR_MALLOC 0x01 /* pattern, act were malloc'd by me */
 } awk_rule;

@@ -83,7 +101,7 @@ typedef struct awk_program_ { /* anchor for the list of
rules */

 extern awk_symtab *awk_new_symtab(void);
 extern void awk_free_symtab(awk_symtab *s);
-extern int awk_declare_sym(awk_symtab *this,
+extern awk_symbol* awk_declare_sym(awk_symtab *this,
                        const char *name,
                        enum awk_symtype type,
                        const void *val,
@@ -118,10 +136,12 @@ extern awk_program *awk_load_program_array(awk_rule
rules[],int nrules);
 extern awk_program *awk_load_program_file(const char *file);
 extern int awk_compile_program(awk_symtab *symtbl,awk_program *rs);
 extern void awk_uncompile_program(awk_program *rs);
-extern int awk_exec_program(awk_program *this, char *buf, int len);
+extern int awk_exec_program(awk_program *this, char *buf, int len, int
hintNum);
 extern int awk_exec_begin_record(awk_program *this);
 extern int awk_exec_end_record(awk_program *this);
 extern int awk_exec_begin(awk_program *this);
 extern int awk_exec_end(awk_program *this);
+extern int awk_set_program_hints(awk_program *this, char *buf, int
hintNum);
+

 #endif /*!AWK_H*/
diff --git a/src/dbfawk.c b/src/dbfawk.c
index 987f1ee..fcac0b9 100644
--- a/src/dbfawk.c
+++ b/src/dbfawk.c
@@ -410,6 +410,8 @@ void dbfawk_parse_record(awk_program *rs,

     for (finfo = fi; finfo ; finfo = finfo->next) {
         char qbuf[1024];
+ //awk_set_program_hints(rs, finfo->name, finfo->num);
+

         switch (finfo->type) {
         case FTString:
@@ -426,7 +428,7 @@ void dbfawk_parse_record(awk_program *rs,
     sprintf(qbuf,"%s=??",finfo->name);
     break;
         }
-        if (awk_exec_program(rs,qbuf,strlen(qbuf)) == 2)
+        if (awk_exec_program(rs,qbuf,strlen(qbuf), finfo->num) == 2)
             break;
     }
     awk_exec_end_record(rs); /* execute an END_RECORD rule if any */
diff --git a/src/map_shp.c b/src/map_shp.c
index 22ba8ef..d99456e 100644
--- a/src/map_shp.c
+++ b/src/map_shp.c
@@ -669,7 +669,8 @@ static awk_rule dbfawk_default_rules[] = {
         0,
         "dbfinfo=\"\"; key=\"\"; lanes=1; color=8; fill_color=13;
fill_stipple=0; name=\"\"; filled=0; fill_style=0; pattern=0;
display_level=65536; label_level=0",
         0,
-        0 },
+        0,
+        -1 },
 };
 #define dbfawk_default_nrules
(sizeof(dbfawk_default_rules)/sizeof(dbfawk_default_rules[0]))
 static dbfawk_sig_info *dbfawk_default_sig = NULL;
@@ -751,6 +752,7 @@ void draw_shapefile_map (Widget w,
     //static int layer;
     dbfawk_sig_info *sig_info = NULL;
     dbfawk_field_info *fld_info = NULL;
+    dbfawk_field_info *fi = NULL;


     int draw_filled_orig;
@@ -955,6 +957,9 @@ void draw_shapefile_map (Widget w,

             /* find out which dbf fields we care to read */
             fld_info = dbfawk_field_list(hDBF, dbffields);
+            for (fi = fld_info; fi ; fi = fi->next)
+                awk_set_program_hints(sig_info->prog, fi->name, fi->num);
+

        } else {                /* should never be reached anymore! */
             fprintf(stderr,"No DBFAWK signature for %s and no
default!\n",filenm);
-- 
1.7.1



On Sat, Feb 5, 2011 at 12:22 PM, Bob Nielsen <n7xy at clearwire.net> wrote:

> Nothing here, so it looks like the list is configured to not pass
> attachments.
>
> I see that gmail's policy of not forwarding a copy to the originator is
> still working :^)
>
> Bob N7XY
>
> On Feb 5, 2011, at 9:58 AM, Jason Godfrey wrote:
>
> > I was looking at the list archive and didn't see any evidence that my
> > attachment made it through. If it did not, please let me know and I will
> > send out another email with the patch pasted in.
> >
> > Thanks
> > - Jason
> >
> >
> > On Fri, Feb 4, 2011 at 9:38 PM, Jason Godfrey <godfreja at gmail.com>
> wrote:
> >
> >> Hello.
> >>
> >> I've been doing some work trying to speed up displaying of shapefile
> maps
> >> using dbfawk. I have a patch that works on the maps I use, and for my
> test
> >> case, speeds drawing up from 30 seconds to 15 seconds. Before I
> officially
> >> submit the patch I woud like to get some more exposure and make sure it
> >> doesn't screw up drawing of some maps.
> >>
> >> If you would like to give it a try, please apply the patch and let me
> know
> >> how it goes for you.
> >>
> >> Thanks
> >> - Jason
> >>
> >>
> >> --
> >> I have learned to use the word 'impossible' with the greatest caution.
>  --
> >> Wernher von Braun
> >>
> >>
> >
> >
> > --
> > I have learned to use the word 'impossible' with the greatest caution.
>  --
> > Wernher von Braun
> > _______________________________________________
> > Xastir-dev mailing list
> > Xastir-dev at lists.xastir.org
> > http://lists.xastir.org/cgi-bin/mailman/listinfo/xastir-dev
>
>


-- 
I have learned to use the word 'impossible' with the greatest caution.  --
Wernher von Braun



More information about the Xastir-dev mailing list