lars        99/03/07 10:03:41

  Modified:    src/modules/standard mod_rewrite.c mod_rewrite.h
               src      CHANGES
               .        STATUS
  Log:
  speed up mod_rewrite...
  
  PR: 3160
  Submitted by: Michael van Elst <[EMAIL PROTECTED]>
  Reviewed by: Jim, Ralf, Lars
  
  Revision  Changes    Path
  1.136     +112 -37   apache-1.3/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.135
  retrieving revision 1.136
  diff -u -r1.135 -r1.136
  --- mod_rewrite.c     1999/01/01 19:50:22     1.135
  +++ mod_rewrite.c     1999/03/07 18:03:34     1.136
  @@ -208,11 +208,7 @@
       /* whether proxy module is available or not */
   static int proxy_available;
   
  -    /* the txt mapfile parsing stuff */
  -static regex_t   *lookup_map_txtfile_regexp = NULL;
  -static regmatch_t lookup_map_txtfile_regmatch[MAX_NMATCH];
   
  -
   /*
   ** +-------------------------------------------------------+
   ** |                                                       |
  @@ -952,10 +948,6 @@
       /* check if proxy module is available */
       proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
   
  -    /* precompile a static pattern
  -       for the txt mapfile parsing */
  -    lookup_map_txtfile_regexp = ap_pregcomp(p, MAPFILE_PATTERN, 
REG_EXTENDED);
  -
       /* create the rewriting lockfile in the parent */
       rewritelock_create(s, p);
       ap_register_cleanup(p, (void *)s, rewritelock_remove, ap_null_cleanup);
  @@ -2729,13 +2721,15 @@
                       else {
                           rewritelog(r, 5, "map lookup FAILED: map=%s[txt] "
                                      "key=%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=%s[txt] key=%s "
                                  "-> val=%s", s->name, key, value);
  -                    return value;
  +                    return value[0] != '\0' ? value : NULL;
                   }
               }
               else if (s->type == MAPTYPE_DBM) {
  @@ -2764,13 +2758,15 @@
                       else {
                           rewritelog(r, 5, "map lookup FAILED: map=%s[dbm] "
                                      "key=%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=%s[dbm] key=%s "
                                  "-> val=%s", s->name, key, value);
  -                    return value;
  +                    return value[0] != '\0' ? value : NULL;
                   }
   #else
                   return NULL;
  @@ -2823,15 +2819,22 @@
                       else {
                           rewritelog(r, 5, "map lookup FAILED: map=%s[txt] "
                                      "key=%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=%s[txt] key=%s "
                                  "-> val=%s", s->name, key, value);
  +                }
  +                if (value[0] != '\0') {
  +                   value = select_random_value_part(r, value);
  +                   rewritelog(r, 5, "randomly choosen the subvalue `%s'", 
value);
  +                }
  +                else {
  +                    value = NULL;
                   }
  -                value = select_random_value_part(r, value);
  -                rewritelog(r, 5, "randomly choosen the subvalue `%s'", 
value);
                   return value;
               }
           }
  @@ -2839,44 +2842,45 @@
       return NULL;
   }
   
  -
   static char *lookup_map_txtfile(request_rec *r, char *file, char *key)
   {
       FILE *fp = NULL;
       char line[1024];
  -    char output[1024];
  -    char result[1024];
       char *value = NULL;
       char *cpT;
  +    size_t skip;
       char *curkey;
       char *curval;
   
       if ((fp = ap_pfopen(r->pool, file, "r")) == NULL) {
  -        return NULL;
  +       return NULL;
       }
   
  -    ap_cpystrn(output, MAPFILE_OUTPUT, sizeof(output));
       while (fgets(line, sizeof(line), fp) != NULL) {
  -        if (line[strlen(line)-1] == '\n') {
  -            line[strlen(line)-1] = '\0';
  -        }
  -        if (regexec(lookup_map_txtfile_regexp, line,
  -                    lookup_map_txtfile_regexp->re_nsub+1,
  -                    lookup_map_txtfile_regmatch, 0) == 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 = strchr(result, ',');
  -            *cpT = '\0';
  -            curkey = result;
  -            curval = cpT+1;
  -
  -            if (strcmp(curkey, key) == 0) {
  -                value = ap_pstrdup(r->pool, curval);
  -                break;
  -            }
  -        }
  +        if (line[0] == '#')
  +            continue; /* ignore comments */
  +        cpT = line;
  +        curkey = cpT;
  +        skip = strcspn(cpT," \t\r\n");
  +        if (skip == 0)
  +            continue; /* ignore lines that start with a space, tab, CR, or 
LF */
  +        cpT += skip;
  +        *cpT = '\0';
  +        if (strcmp(curkey, key) != 0)
  +            continue; /* key does not match... */
  +            
  +        /* found a matching key; now extract and return the value */
  +        ++cpT;
  +        skip = strspn(cpT, " \t\r\n");
  +        cpT += skip;
  +        curval = cpT;
  +        skip = strcspn(cpT, " \t\r\n");
  +        if (skip == 0)
  +            continue; /* no value... */
  +        cpT += skip;
  +        *cpT = '\0';
  +        value = ap_pstrdup(r->pool, curval);
  +        break;
       }
       ap_pfclose(r->pool, fp);
       return value;
  @@ -3834,12 +3838,57 @@
       return ap_pstrdup(c->pool, ce->value);
   }
   
  +static int cache_tlb_hash(char *key)
  +{
  +    unsigned long n;
  +    char *p;
  +
  +    n = 0;
  +    for (p=key; *p != '\0'; ++p) {
  +        n = n * 53711 + 134561 + (unsigned)(*p & 0xff);
  +    }
  +
  +    return n % CACHE_TLB_ROWS;
  +}
  +
  +static cacheentry *cache_tlb_lookup(cachetlbentry *tlb, cacheentry *elt,
  +                                    char *key)
  +{
  +    int ix = cache_tlb_hash(key);
  +    int i;
  +    int j;
  +
  +    for (i=0; i < CACHE_TLB_COLS; ++i) {
  +        j = tlb[ix].t[i];
  +        if (j < 0)
  +            return NULL;
  +        if (strcmp(elt[j].key, key) == 0)
  +            return &elt[j];
  +    }
  +    return NULL;
  +}
  +
  +static void cache_tlb_replace(cachetlbentry *tlb, cacheentry *elt,
  +                              cacheentry *e)
  +{
  +    int ix = cache_tlb_hash(e->key);
  +    int i;
  +
  +    tlb = &tlb[ix];
  +
  +    for (i=1; i < CACHE_TLB_COLS; ++i)
  +        tlb->t[i] = tlb->t[i-1];
  +
  +    tlb->t[0] = 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 = 0;
  @@ -3848,11 +3897,22 @@
           l = &(((cachelist *)c->lists->elts)[i]);
           if (strcmp(l->resource, res) == 0) {
               found_list = 1;
  +
  +            e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts,
  +                                 (cacheentry *)l->entries->elts, ce->key);
  +            if (e != NULL) {
  +                e->time  = ce->time;
  +                e->value = ap_pstrdup(c->pool, ce->value);
  +                return;
  +            }
  +
               for (j = 0; j < l->entries->nelts; j++) {
                   e = &(((cacheentry *)l->entries->elts)[j]);
                   if (strcmp(e->key, ce->key) == 0) {
                       e->time  = ce->time;
                       e->value = ap_pstrdup(c->pool, ce->value);
  +                  cache_tlb_replace((cachetlbentry *)l->tlb->elts,
  +                                    (cacheentry *)l->entries->elts, e);
                       return;
                   }
               }
  @@ -3864,6 +3924,13 @@
           l = ap_push_array(c->lists);
           l->resource = ap_pstrdup(c->pool, res);
           l->entries  = ap_make_array(c->pool, 2, sizeof(cacheentry));
  +        l->tlb      = ap_make_array(c->pool, CACHE_TLB_ROWS,
  +                                    sizeof(cachetlbentry));
  +        for (i=0; i<CACHE_TLB_ROWS; ++i) {
  +            t = &((cachetlbentry *)l->tlb->elts)[i];
  +                for (j=0; j<CACHE_TLB_COLS; ++j)
  +                    t->t[j] = -1;
  +        }
       }
   
       /* create the new entry */
  @@ -3874,6 +3941,8 @@
               e->time  = ce->time;
               e->key   = ap_pstrdup(c->pool, ce->key);
               e->value = ap_pstrdup(c->pool, ce->value);
  +            cache_tlb_replace((cachetlbentry *)l->tlb->elts,
  +                              (cacheentry *)l->entries->elts, e);
               return;
           }
       }
  @@ -3892,6 +3961,12 @@
       for (i = 0; i < c->lists->nelts; i++) {
           l = &(((cachelist *)c->lists->elts)[i]);
           if (strcmp(l->resource, res) == 0) {
  +
  +            e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts,
  +                                 (cacheentry *)l->entries->elts, key);
  +            if (e != NULL)
  +                return e;
  +
               for (j = 0; j < l->entries->nelts; j++) {
                   e = &(((cacheentry *)l->entries->elts)[j]);
                   if (strcmp(e->key, key) == 0) {
  
  
  
  1.61      +14 -8     apache-1.3/src/modules/standard/mod_rewrite.h
  
  Index: mod_rewrite.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -r1.60 -r1.61
  --- mod_rewrite.h     1999/01/28 07:15:18     1.60
  +++ mod_rewrite.h     1999/03/07 18:03:37     1.61
  @@ -219,6 +219,9 @@
   #define CACHEMODE_TS                1<<0
   #define CACHEMODE_TTL               1<<1
   
  +#define CACHE_TLB_ROWS 1024
  +#define CACHE_TLB_COLS 4
  +
   #ifndef FALSE
   #define FALSE 0
   #define TRUE  !FALSE
  @@ -241,10 +244,6 @@
   
   #define MAX_NMATCH    10
   
  -#define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$"
  -#define MAPFILE_OUTPUT  "$1,$2"
  -
  -
   /*
   **
   **  our private data structures we handle with
  @@ -317,17 +316,23 @@
   } rewrite_perdir_conf;
   
   
  -    /* the cache structures */
  -
  +    /* the cache structures,
  +     * a 4-way hash table with LRU functionality
  +     */
   typedef struct cacheentry {
       time_t time;
       char  *key;
       char  *value;
   } cacheentry;
   
  +typedef struct tlbentry {
  +    int t[CACHE_TLB_COLS];
  +} cachetlbentry;
  +
   typedef struct cachelist {
       char         *resource;
       array_header *entries;
  +    array_header *tlb;
   } cachelist;
   
   typedef struct cache {
  @@ -335,9 +340,10 @@
       array_header *lists;
   } cache;
   
  -    /* the regex structure for the
  -       substitution of backreferences */
   
  +    /* the regex structure for the
  +     * substitution of backreferences
  +     */
   typedef struct backrefinfo {
       char *source;
       int nsub;
  
  
  
  1.1264    +10 -0     apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1263
  retrieving revision 1.1264
  diff -u -r1.1263 -r1.1264
  --- CHANGES   1999/03/07 15:35:14     1.1263
  +++ CHANGES   1999/03/07 18:03:38     1.1264
  @@ -1,5 +1,15 @@
   Changes with Apache 1.3.5
   
  +  *) Enhanced mod_rewrite's mapfile handling: The in-core cache for text and
  +     DBM format mapfiles now uses a 4-way hash table with LRU functionality.
  +     Furthermore map lookups for non-existent keys are now cached as well.
  +     Additionally "txt" maps are now parsed with simple string functions
  +     instead of using ap_pregcomp(). As a side effect a bug that prevented
  +     the usage of keys containing the "," character was fixed.
  +     The changes drastically improve the performance when large rewrite maps
  +     are in use.
  +     [Michael van Elst <[EMAIL PROTECTED]>, Lars Eilebrecht] PR#3160
  +
     *) Added ap_sub_req_method_uri() for doing a subrequest with a method
        other than GET, and const'd the definition of method in request_rec.
        [Greg Stein]
  
  
  
  1.639     +1 -9      apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.638
  retrieving revision 1.639
  diff -u -r1.638 -r1.639
  --- STATUS    1999/03/07 16:56:49     1.638
  +++ STATUS    1999/03/07 18:03:41     1.639
  @@ -1,5 +1,5 @@
     1.3 STATUS:
  -  Last modified at [$Date: 1999/03/07 16:56:49 $]
  +  Last modified at [$Date: 1999/03/07 18:03:41 $]
   
   Release:
   
  @@ -113,14 +113,6 @@
       * Ronald Tschalär's ap_uuencode() bugfix
           Message-ID: PR#3411
           Status: Lars +1 (on concept), Dirkx +1
  -
  -    * Michael van Elst's patch [PR#3160] to improve mod_rewrite's
  -      in-core cache handling by using a hash table.
  -        Message-ID: <[EMAIL PROTECTED]>
  -        Status: Lars +1, Jim +1, Ralf +1 (on concept, but because the code
  -                                          change is not trivial I want to
  -                                          first walk though it line by line 
  -                                          the next days before we commit it).
   
       * Juan Gallego's patch to add CSH-style modifiers (:h, :r, :t, :e)
         to mod_include's variable processing.
  
  
  

Reply via email to