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 <[email protected]> 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 <[email protected]> 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 <[email protected]> > 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 > > [email protected] > > 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 _______________________________________________ Xastir-dev mailing list [email protected] http://lists.xastir.org/cgi-bin/mailman/listinfo/xastir-dev
