The following reply was made to PR mod_rewrite/3160; it has been noted by GNATS.
From: Michael van Elst <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
Subject: Re: mod_rewrite/3160: processing rewrite maps is slow
Date: Sun, 11 Oct 1998 23:27:04 +0200 (MEST)
> Synopsis: processing rewrite maps is slow
>
> Comment-Added-By: lars
> Comment-Added-When: Fri Oct 9 03:07:05 PDT 1998
> Comment-Added:
>
> Thank you for your report.
> It would be very helpful if you generate a (unified) diff
> for your patch and attach it to this report
> (reply to this mail or put =B4mod_rewrite/3160:=B4 in the
> subject line and send it to [EMAIL PROTECTED]).
Here are the diffs to mod_rewrite.c and mod_rewrite.h
--------------- snip ----------------------
--- mod_rewrite.c.original Wed Oct 7 15:44:28 1998
+++ mod_rewrite.c Wed Oct 7 15:46:39 1998
@@ -208,10 +208,6 @@
/* whether proxy module is available or not */
static int proxy_available;
- /* the txt mapfile parsing stuff */
-static regex_t *lookup_map_txtfile_regexp =3D NULL;
-static regmatch_t lookup_map_txtfile_regmatch[MAX_NMATCH];
-
/*
** +-------------------------------------------------------+
@@ -937,10 +933,6 @@
/* check if proxy module is available */
proxy_available =3D (ap_find_linked_module("mod_proxy.c") !=3D NULL);
- /* precompile a static pattern
- for the txt mapfile parsing */
- lookup_map_txtfile_regexp =3D ap_pregcomp(p, MAPFILE_PATTERN, REG_EXTE=
NDED);
-
/* create the rewriting lockfile in the parent */
rewritelock_create(s, p);
ap_register_cleanup(p, (void *)s, rewritelock_remove, ap_null_cleanup)=
;
@@ -2695,13 +2687,15 @@
else {
rewritelog(r, 5, "map lookup FAILED: map=3D%s[txt]=
"
"key=3D%s", s->name, key);
+ set_cache_string(cachep, s->name, CACHEMODE_TS,
+ st.st_mtime, key, "");
return NULL;
}
}
else {
rewritelog(r, 5, "cache lookup OK: map=3D%s[txt] key=
=3D%s "
"-> val=3D%s", s->name, key, value);
- return value;
+ return value[0] !=3D '\0' ? value : NULL;
}
}
else if (s->type =3D=3D MAPTYPE_DBM) {
@@ -2730,13 +2724,15 @@
else {
rewritelog(r, 5, "map lookup FAILED: map=3D%s[dbm]=
"
"key=3D%s", s->name, key);
+ set_cache_string(cachep, s->name, CACHEMODE_TS,
+ st.st_mtime, key, "");
return NULL;
}
}
else {
rewritelog(r, 5, "cache lookup OK: map=3D%s[dbm] key=
=3D%s "
"-> val=3D%s", s->name, key, value);
- return value;
+ return value[0] !=3D '\0' ? value : NULL;
}
#else
return NULL;
@@ -2789,6 +2785,8 @@
else {
rewritelog(r, 5, "map lookup FAILED: map=3D%s[txt]=
"
"key=3D%s", s->name, key);
+ set_cache_string(cachep, s->name, CACHEMODE_TS,
+ st.st_mtime, key, "");
return NULL;
}
}
@@ -2796,8 +2794,12 @@
rewritelog(r, 5, "cache lookup OK: map=3D%s[txt] key=
=3D%s "
"-> val=3D%s", s->name, key, value);
}
- value =3D select_random_value_part(r, value);
- rewritelog(r, 5, "randomly choosen the subvalue `%s'", val=
ue);
+ if (value[0] !=3D '\0') {
+ value =3D select_random_value_part(r, value);
+ rewritelog(r, 5, "randomly choosen the subvalue `%s'", =
value);
+ } else {
+ value =3D NULL;
+ }
return value;
}
}
@@ -2805,15 +2807,13 @@
return NULL;
}
-
static char *lookup_map_txtfile(request_rec *r, char *file, char *key)
{
FILE *fp =3D NULL;
char line[1024];
- char output[1024];
- char result[1024];
char *value =3D NULL;
char *cpT;
+ size_t skip;
char *curkey;
char *curval;
@@ -2821,27 +2821,29 @@
return NULL;
}
- ap_cpystrn(output, MAPFILE_OUTPUT, sizeof(output));
while (fgets(line, sizeof(line), fp) !=3D NULL) {
- if (line[strlen(line)-1] =3D=3D '\n') {
- line[strlen(line)-1] =3D '\0';
- }
- if (regexec(lookup_map_txtfile_regexp, line,
- lookup_map_txtfile_regexp->re_nsub+1,
- lookup_map_txtfile_regmatch, 0) =3D=3D 0) {
- ap_cpystrn(result, ap_pregsub(r->pool, output, line,
- lookup_map_txtfile_regexp->re_nsub+1,
- lookup_map_txtfile_regmatch),
- sizeof(result)); /* substitute in output */
- cpT =3D strchr(result, ',');
- *cpT =3D '\0';
- curkey =3D result;
- curval =3D cpT+1;
-
- if (strcmp(curkey, key) =3D=3D 0) {
- value =3D ap_pstrdup(r->pool, curval);
- break;
- }
+ if (line[0] =3D=3D '#')
+ continue;
+ cpT =3D line;
+ curkey =3D cpT;
+ skip =3D strcspn(cpT," \t\n");
+ if (skip =3D=3D 0)
+ continue;
+ cpT +=3D skip;
+ *cpT =3D '\0';
+ ++cpT;
+ skip =3D strspn(cpT, " \t\n");
+ cpT +=3D skip;
+ curval =3D cpT;
+ skip =3D strcspn(cpT, " \t\n");
+ if (skip =3D=3D 0)
+ continue;
+ cpT +=3D skip;
+ *cpT =3D '\0';
+
+ if (strcmp(curkey, key) =3D=3D 0) {
+ value =3D ap_pstrdup(r->pool, curval);
+ break;
}
}
ap_pfclose(r->pool, fp);
@@ -3780,12 +3782,61 @@
return ap_pstrdup(c->pool, ce->value);
}
+static int cache_tlb_hash(char *key)
+{
+ unsigned long n;
+ char *p;
+
+ n =3D 0;
+ for (p=3Dkey; *p !=3D '\0'; ++p) {
+ n =3D n * 53711 + 134561 + (unsigned)(*p & 0xff);
+ }
+
+ return n % CACHE_TLB_ROWS;
+}
+
+static cacheentry *cache_tlb_lookup(
+ cachetlbentry *tlb,
+ cacheentry *elt,
+ char *key)
+{
+ int ix =3D cache_tlb_hash(key);
+ int i;
+ int j;
+
+ for (i=3D0; i<CACHE_TLB_COLS; ++i) {
+ j =3D tlb[ix].t[i];
+ if (j < 0)
+ return NULL;
+ if (strcmp(elt[j].key, key) =3D=3D 0)
+ return &elt[j];
+ }
+ return NULL;
+}
+
+static void cache_tlb_replace(
+ cachetlbentry *tlb,
+ cacheentry *elt,
+ cacheentry *e)
+{
+ int ix =3D cache_tlb_hash(e->key);
+ int i;
+
+ tlb =3D &tlb[ix];
+
+ for (i=3D1; i<CACHE_TLB_COLS; ++i)
+ tlb->t[i] =3D tlb->t[i-1];
+
+ tlb->t[0] =3D e - elt;
+}
+
static void store_cache_string(cache *c, char *res, cacheentry *ce)
{
int i;
int j;
cachelist *l;
cacheentry *e;
+ cachetlbentry *t;
int found_list;
found_list =3D 0;
@@ -3794,11 +3845,25 @@
l =3D &(((cachelist *)c->lists->elts)[i]);
if (strcmp(l->resource, res) =3D=3D 0) {
found_list =3D 1;
+
+ e =3D cache_tlb_lookup(
+ (cachetlbentry *)l->tlb->elts,
+ (cacheentry *)l->entries->elts,
+ ce->key);
+ if (e !=3D NULL) {
+ e->time =3D ce->time;
+ e->value =3D ap_pstrdup(c->pool, ce->value);
+ return;
+ }
+
for (j =3D 0; j < l->entries->nelts; j++) {
e =3D &(((cacheentry *)l->entries->elts)[j]);
if (strcmp(e->key, ce->key) =3D=3D 0) {
e->time =3D ce->time;
e->value =3D ap_pstrdup(c->pool, ce->value);
+ cache_tlb_replace((cachetlbentry *)l->tlb->elts,
+ (cacheentry *)l->entries->elts,
+ e);
return;
}
}
@@ -3810,6 +3875,14 @@
l =3D ap_push_array(c->lists);
l->resource =3D ap_pstrdup(c->pool, res);
l->entries =3D ap_make_array(c->pool, 2, sizeof(cacheentry));
+ l->tlb =3D ap_make_array(c->pool,
+ CACHE_TLB_ROWS,
+ sizeof(cachetlbentry));
+ for (i=3D0; i<CACHE_TLB_ROWS; ++i) {
+ t =3D &((cachetlbentry *)l->tlb->elts)[i];
+ for (j=3D0; j<CACHE_TLB_COLS; ++j)
+ t->t[j] =3D -1;
+ }
}
/* create the new entry */
@@ -3820,6 +3893,9 @@
e->time =3D ce->time;
e->key =3D ap_pstrdup(c->pool, ce->key);
e->value =3D ap_pstrdup(c->pool, ce->value);
+ cache_tlb_replace((cachetlbentry *)l->tlb->elts,
+ (cacheentry *)l->entries->elts,
+ e);
return;
}
}
@@ -3838,6 +3914,14 @@
for (i =3D 0; i < c->lists->nelts; i++) {
l =3D &(((cachelist *)c->lists->elts)[i]);
if (strcmp(l->resource, res) =3D=3D 0) {
+
+ e =3D cache_tlb_lookup(
+ (cachetlbentry *)l->tlb->elts,
+ (cacheentry *)l->entries->elts,
+ key);
+ if (e !=3D NULL)
+ return e;
+
for (j =3D 0; j < l->entries->nelts; j++) {
e =3D &(((cacheentry *)l->entries->elts)[j]);
if (strcmp(e->key, key) =3D=3D 0) {
--- mod_rewrite.h.original Wed Oct 7 15:44:30 1998
+++ mod_rewrite.h Wed Oct 7 15:44:29 1998
@@ -233,10 +233,6 @@
#define MAX_NMATCH 10
-#define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$"
-#define MAPFILE_OUTPUT "$1,$2"
-
-
/*
**
** our private data structures we handle with
@@ -317,9 +313,17 @@
char *value;
} cacheentry;
+#define CACHE_TLB_ROWS 1024
+#define CACHE_TLB_COLS 4
+
+typedef struct tlbentry {
+ int t[CACHE_TLB_COLS];
+} cachetlbentry;
+
typedef struct cachelist {
char *resource;
array_header *entries;
+ array_header *tlb;
} cachelist;
typedef struct cache {
--------------- snap ----------------------
--
Michael van Elst
Internet: [EMAIL PROTECTED]
"A potential Snark may lurk in every tree."