dgaudet     97/08/17 13:21:38

  Modified:    src/core http_core.c http_request.c
  Log:
  Fix a bug introduced during the directory_walk() optimizations most recently
  checked in.  Includes a rewrite of core_reorder_directories, and removes
  some cruft code from {directory,file,locaiton}_walk.
  
  Reviewed by:  Rob Hartill
  
  Revision  Changes    Path
  1.111     +72 -56    apachen/src/core/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_core.c,v
  retrieving revision 1.110
  retrieving revision 1.111
  diff -u -r1.110 -r1.111
  --- http_core.c       1997/08/17 11:14:34     1.110
  +++ http_core.c       1997/08/17 20:21:36     1.111
  @@ -237,74 +237,90 @@
       *new_space = url_config;
   }
   
  -/* This routine reorders the directory sections such that the 1-component
  - * sections come first, then the 2-component, and so on, finally followed by
  - * the "special" sections.  A section is "special" if it's a regex, or if it
  - * doesn't start with / -- consider proxy: matching.  All movements are
  - * in-order to preserve the ordering of the sections from the config files.
  +/* core_reorder_directories reorders the directory sections such that the
  + * 1-component sections come first, then the 2-component, and so on, finally
  + * followed by the "special" sections.  A section is "special" if it's a 
regex,
  + * or if it doesn't start with / -- consider proxy: matching.  All movements
  + * are in-order to preserve the ordering of the sections from the config 
files.
    * See directory_walk().
    */
  +
  +#define IS_SPECIAL(entry_core)       \
  +    ((entry_core)->r != NULL || (entry_core)->d[0] != '/')
  +
  +/* We need to do a stable sort, qsort isn't stable.  So to make it stable
  + * we'll be maintaining the original index into the list, and using it
  + * as the minor key during sorting.  The major key is the number of
  + * components (where a "special" section has infinite components).
  + */
  +struct reorder_sort_rec {
  +    void *elt;
  +    int orig_index;
  +};
  +
  +static int reorder_sorter (const void *va, const void *vb)
  +{
  +    const struct reorder_sort_rec *a = va;
  +    const struct reorder_sort_rec *b = vb;
  +    core_dir_config *core_a;
  +    core_dir_config *core_b;
  +
  +    core_a = (core_dir_config *)get_module_config (a->elt, &core_module);
  +    core_b = (core_dir_config *)get_module_config (b->elt, &core_module);
  +    if (IS_SPECIAL(core_a)) {
  +     if (!IS_SPECIAL(core_b)) {
  +         return 1;
  +     }
  +    } else if (IS_SPECIAL(core_b)) {
  +     return -1;
  +    } else {
  +     /* we know they're both not special */
  +     if (core_a->d_components < core_b->d_components) {
  +         return -1;
  +     } else if (core_a->d_components > core_b->d_components) {
  +         return 1;
  +     }
  +    }
  +    /* Either their both special, or their both not special and have the
  +     * same number of components.  In any event, we now have to compare
  +     * the minor key. */
  +    return a->orig_index - b->orig_index;
  +}
  +
   void core_reorder_directories (pool *p, server_rec *s)
   {
       core_server_config *sconf;
  -    array_header *old_sec;
  -    array_header *new_sec;
  +    array_header *sec;
  +    struct reorder_sort_rec *sortbin;
       int nelts;
  -    unsigned n_components;
  -    unsigned next_n_components;
  -    core_dir_config *entry_core;
  -    int still_more_to_go;
  -    int i;
       void **elts;
  +    int i;
   
  -    sconf = get_module_config (s->module_config, &core_module);
  -    old_sec = sconf->sec;
  -    nelts = old_sec->nelts;
  -    elts = (void **)old_sec->elts;
  -    new_sec = make_array (p, nelts, sizeof(void *));
  -
  -    /* First collect all the 1 component names, then the 2 componennt names,
  -     * and so on.  We use next_n_components to know what to look for the
  -     * next time around... to deal with weird configs with many many many
  -     * in at least one <Directory>.
  +    /* XXX: we are about to waste some ram ... we will build a new array
  +     * and we need some scratch space to do it.  The old array and the
  +     * scratch space are never freed.
        */
  -    n_components = 1;
  -    do {
  -     /* guess there's none left other than ones with exactly n_components */
  -     still_more_to_go = 0;
  -     /* guess that what's left has infinite components */
  -     next_n_components = ~0u;
  -     for (i = 0; i < nelts; ++i) {
  -         if (elts[i] == NULL) continue;
  -         entry_core = (core_dir_config *)get_module_config (elts[i],
  -                                                         &core_module);
  -         if (entry_core->r) continue;
  -         if (entry_core->d[0] != '/') continue;
  -         if (entry_core->d_components != n_components) {
  -             /* oops, the guess was wrong */
  -             still_more_to_go = 1;
  -             if (entry_core->d_components < next_n_components) {
  -                 next_n_components = entry_core->d_components;
  -             }
  -             continue;
  -         }
  -         *(void **)push_array (new_sec) = elts[i];
  -         elts[i] = NULL;
  -     }
  -     n_components = next_n_components;
  -    } while (still_more_to_go);
  -    
  -    /* anything left is a "special" case */
  +    sconf = get_module_config (s->module_config, &core_module);
  +    sec = sconf->sec;
  +    nelts = sec->nelts;
  +    elts = (void **)sec->elts;
  +
  +    /* build our sorting space */
  +    sortbin = palloc (p, sec->nelts * sizeof (*sortbin));
       for (i = 0; i < nelts; ++i) {
  -     if (elts[i] == NULL) continue;
  -     *(void **)push_array (new_sec) = elts[i];
  +     sortbin[i].orig_index = i;
  +     sortbin[i].elt = elts[i];
       }
   
  -    /* XXX: in theory we could have allocated new_sec from the ptemp
  -     * pool, and then memcpy'd it over top of old_sec ... oh well,
  -     * we're wasting some ram here.
  -     */
  -    sconf->sec = new_sec;
  +    qsort (sortbin, nelts, sizeof (*sortbin), reorder_sorter);
  +
  +    /* and now build a new array */
  +    sec = make_array (p, nelts, sizeof (void *));
  +    for (i = 0; i < nelts; ++i) {
  +     *(void **)push_array (sec) = sortbin[i].elt;
  +    }
  +
  +    sconf->sec = sec;
   }
   
   /*****************************************************************
  
  
  
  1.75      +6 -16     apachen/src/core/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apachen/src/core/http_request.c,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -r1.74 -r1.75
  --- http_request.c    1997/08/09 11:52:04     1.74
  +++ http_request.c    1997/08/17 20:21:36     1.75
  @@ -246,11 +246,9 @@
   {
       core_server_config *sconf = get_module_config (r->server->module_config,
                                                   &core_module);
  -    array_header *sec_array = copy_array (r->pool, sconf->sec);
       void *per_dir_defaults = r->server->lookup_defaults;
  -    
  -    core_dir_config **sec = (core_dir_config **)sec_array->elts;
  -    int num_sec = sec_array->nelts;
  +    void **sec = (void **)sconf->sec->elts;
  +    int num_sec = sconf->sec->nelts;
       char *test_filename = pstrdup (r->pool, r->filename);
       char *test_dirname;
       int res;
  @@ -294,7 +292,6 @@
        for (j = 0; j < num_sec; ++j) {
   
            entry_config = sec[j];
  -         if (!entry_config) continue;
            
            entry_core =(core_dir_config *)
                get_module_config(entry_config, &core_module);
  @@ -387,7 +384,6 @@
            this_conf = NULL;
            if (entry_core->d_is_fnmatch) {
                if (!fnmatch(entry_dir, test_dirname, FNM_PATHNAME)) {
  -                 sec[j] = NULL;      
                    this_conf = entry_config;
                }
            }
  @@ -467,11 +463,9 @@
   {
       core_server_config *sconf = get_module_config (r->server->module_config,
                                                   &core_module);
  -    array_header *url_array = copy_array (r->pool, sconf->sec_url);
       void *per_dir_defaults = r->per_dir_config;
  -    
  -    core_dir_config **url = (core_dir_config **)url_array->elts;
  -    int len, num_url = url_array->nelts;
  +    void **url = (void **)sconf->sec_url->elts;
  +    int len, num_url = sconf->sec_url->nelts;
       char *test_location = pstrdup (r->pool, r->uri);
   
       /* Collapse multiple slashes, if it's a path URL (we don't want to
  @@ -495,7 +489,6 @@
        for (j = 0; j < num_url; ++j) {
   
            entry_config = url[j];
  -         if (!entry_config) continue;
            
            entry_core =(core_dir_config *)
                get_module_config(entry_config, &core_module);
  @@ -533,11 +526,9 @@
   int file_walk (request_rec *r)
   {
       core_dir_config *conf = get_module_config(r->per_dir_config, 
&core_module);
  -    array_header *file_array = copy_array (r->pool, conf->sec);
       void *per_dir_defaults = r->per_dir_config;
  -    
  -    core_dir_config **file = (core_dir_config **)file_array->elts;
  -    int len, num_files = file_array->nelts;
  +    void **file = (void **)conf->sec->elts;
  +    int len, num_files = conf->sec->nelts;
       char *test_file = pstrdup (r->pool, r->filename);
   
       /* Collapse multiple slashes */
  @@ -558,7 +549,6 @@
        for (j = 0; j < num_files; ++j) {
   
            entry_config = file[j];
  -         if (!entry_config) continue;
            
            entry_core =(core_dir_config *)
                get_module_config(entry_config, &core_module);
  
  
  

Reply via email to