[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