You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Brian Pane <bp...@pacbell.net> on 2001/06/27 18:50:36 UTC

[PATCH] mod_mime performance tweaks, revised

I've revised my mod_mime optimization patch a bit
to try to speed up the merge-per-dir-config implementation.
This patch replaces the previous one that I posted.  (That's the
last of my changes, I promise, until somebody reviews this
one :-)

--Brian

Index: mod_mime.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/http/mod_mime.c,v
retrieving revision 1.42
diff -u -r1.42 mod_mime.c
--- mod_mime.c    2001/06/18 05:36:31    1.42
+++ mod_mime.c    2001/06/27 16:47:35
@@ -66,6 +66,7 @@
 #include "apr.h"
 #include "apr_strings.h"
 #include "apr_lib.h"
+#include "apr_hash.h"
 
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
@@ -96,12 +97,19 @@
     char *name;
 } attrib_info;
 
+/* Information to which an extension can be mapped
+ */
+typedef struct extension_info {
+    char *forced_type;                /* Additional AddTyped stuff */
+    char *encoding_type;              /* Added with AddEncoding... */
+    char *language_type;              /* Added with AddLanguage... */
+    char *handler;                    /* Added with AddHandler... */
+    char *charset_type;               /* Added with AddCharset... */
+} extension_info;
+
 typedef struct {
-    apr_table_t *forced_types;        /* Additional AddTyped stuff */
-    apr_table_t *encoding_types;      /* Added with AddEncoding... */
-    apr_table_t *language_types;      /* Added with AddLanguage... */
-    apr_table_t *handlers;            /* Added with AddHandler...  */
-    apr_table_t *charset_types;       /* Added with AddCharset... */      
+    apr_hash_t  *extension_mappings;  /* Map from extension name to
+                       * extension_info structure */
     apr_array_header_t *handlers_remove;  /* List of handlers to remove */
     apr_array_header_t *types_remove;     /* List of MIME types to 
remove */
     apr_array_header_t *encodings_remove; /* List of encodings to remove */
@@ -138,14 +146,10 @@
     mime_dir_config *new =
     (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
 
-    new->forced_types = apr_table_make(p, 4);
-    new->encoding_types = apr_table_make(p, 4);
-    new->charset_types = apr_table_make(p, 4);
-    new->language_types = apr_table_make(p, 4);
-    new->handlers = apr_table_make(p, 4);
-    new->handlers_remove = apr_array_make(p, 4, sizeof(attrib_info));
-    new->types_remove = apr_array_make(p, 4, sizeof(attrib_info));
-    new->encodings_remove = apr_array_make(p, 4, sizeof(attrib_info));
+    new->extension_mappings = apr_hash_make(p);
+    new->handlers_remove = NULL;
+    new->types_remove = NULL;
+    new->encodings_remove = NULL;
 
     new->type = NULL;
     new->handler = NULL;
@@ -154,41 +158,107 @@
     return new;
 }
 
+/*
+ * Overlay one hash table of extension_mappings onto another
+ */
+static void overlay_extension_mappings(apr_pool_t *p,
+                       apr_hash_t *overlay, apr_hash_t *base)
+{
+    apr_hash_index_t *index;
+    for (index = apr_hash_first(overlay); index;
+     index = apr_hash_next(index)) {
+    char *key;
+    apr_ssize_t klen;
+    extension_info *overlay_info, *base_info;
+
+    apr_hash_this(index, (const void**)&key, &klen, (void**)&overlay_info);
+    base_info = (extension_info*)apr_hash_get(base, key, klen);
+    if (base_info) {
+        if (overlay_info->forced_type) {
+        base_info->forced_type = overlay_info->forced_type;
+        }
+        if (overlay_info->encoding_type) {
+        base_info->encoding_type = overlay_info->encoding_type;
+        }
+        if (overlay_info->language_type) {
+        base_info->language_type = overlay_info->language_type;
+        }
+        if (overlay_info->handler) {
+        base_info->handler = overlay_info->handler;
+        }
+        if (overlay_info->charset_type) {
+        base_info->charset_type = overlay_info->charset_type;
+        }
+    }
+    else {
+        base_info = (extension_info*)apr_palloc(p, sizeof(extension_info));
+        memcpy(base_info, overlay_info, sizeof(extension_info));
+        apr_hash_set(base, key, klen, base_info);
+    }
+    }
+}
+
 static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
 {
     mime_dir_config *base = (mime_dir_config *) basev;
     mime_dir_config *add = (mime_dir_config *) addv;
-    mime_dir_config *new =
-        (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
+    mime_dir_config *new = apr_pcalloc(p, sizeof(mime_dir_config));
+
     int i;
     attrib_info *suffix;
 
-    new->forced_types = apr_table_overlay(p, add->forced_types,
-                     base->forced_types);
-    new->encoding_types = apr_table_overlay(p, add->encoding_types,
-                                         base->encoding_types);
-    new->charset_types = apr_table_overlay(p, add->charset_types,
-                       base->charset_types);
-    new->language_types = apr_table_overlay(p, add->language_types,
-                                         base->language_types);
-    new->handlers = apr_table_overlay(p, add->handlers,
-                                   base->handlers);
-
-    suffix = (attrib_info *) add->handlers_remove->elts;
-    for (i = 0; i < add->handlers_remove->nelts; i++) {
-        apr_table_unset(new->handlers, suffix[i].name);
-    }
-
-    suffix = (attrib_info *) add->types_remove->elts;
-    for (i = 0; i < add->types_remove->nelts; i++) {
-        apr_table_unset(new->forced_types, suffix[i].name);
-    }
-
-    suffix = (attrib_info *) add->encodings_remove->elts;
-    for (i = 0; i < add->encodings_remove->nelts; i++) {
-        apr_table_unset(new->encoding_types, suffix[i].name);
+    if (base->extension_mappings == NULL) {
+    new->extension_mappings = add->extension_mappings;
     }
+    else if (add->extension_mappings == NULL) {
+    new->extension_mappings = base->extension_mappings;
+    }
+    else {
+    new->extension_mappings = apr_hash_make(p);
+    overlay_extension_mappings(p, base->extension_mappings,
+                   new->extension_mappings);
+    overlay_extension_mappings(p, add->extension_mappings,
+                   new->extension_mappings);
+    }
+
+    if (add->handlers_remove) {
+    suffix = (attrib_info *) add->handlers_remove->elts;
+    for (i = 0; i < add->handlers_remove->nelts; i++) {
+        extension_info *exinfo =
+        (extension_info*)apr_hash_get(new->extension_mappings,
+                          suffix[i].name,
+                          APR_HASH_KEY_STRING);
+        if (exinfo) {
+        exinfo->handler = NULL;
+        }
+    }
+    }
 
+    if (add->types_remove) {
+    suffix = (attrib_info *) add->types_remove->elts;
+    for (i = 0; i < add->types_remove->nelts; i++) {
+        extension_info *exinfo =
+        (extension_info*)apr_hash_get(new->extension_mappings,
+                          suffix[i].name,
+                          APR_HASH_KEY_STRING);
+        if (exinfo) {
+        exinfo->forced_type = NULL;
+        }
+    }
+    }
+
+    if (add->encodings_remove) {
+    suffix = (attrib_info *) add->encodings_remove->elts;
+    for (i = 0; i < add->encodings_remove->nelts; i++) {
+        extension_info *exinfo =
+        (extension_info*)apr_hash_get(new->extension_mappings,
+                          suffix[i].name,
+                          APR_HASH_KEY_STRING);
+        if (exinfo) {
+        exinfo->encoding_type = NULL;
+        }
+    }
+    }
 
     new->type = add->type ? add->type : base->type;
     new->handler = add->handler ? add->handler : base->handler;
@@ -198,17 +268,33 @@
     return new;
 }
 
+static extension_info *get_extension_info(apr_pool_t *p, 
mime_dir_config *m,
+                      const char* key)
+{
+    extension_info *exinfo;
+
+    exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key,
+                       APR_HASH_KEY_STRING);
+    if (!exinfo) {
+    exinfo = apr_pcalloc(p, sizeof(extension_info));
+    apr_hash_set(m->extension_mappings, apr_pstrdup(p, key),
+             APR_HASH_KEY_STRING, exinfo);
+    }
+    return exinfo;
+}
+
 static const char *add_type(cmd_parms *cmd, void *m_, const char *ct_,
                             const char *ext)
 {
     mime_dir_config *m=m_;
     char *ct=apr_pstrdup(cmd->pool,ct_);
+    extension_info* exinfo;
 
     if (*ext == '.')
     ++ext;
-   
+    exinfo = get_extension_info(cmd->pool, m, ext);
     ap_str_tolower(ct);
-    apr_table_setn(m->forced_types, ext, ct);
+    exinfo->forced_type = ct;
     return NULL;
 }
 
@@ -217,11 +303,13 @@
 {
     mime_dir_config *m=m_;
     char *enc=apr_pstrdup(cmd->pool,enc_);
+    extension_info* exinfo;
 
     if (*ext == '.')
         ++ext;
+    exinfo = get_extension_info(cmd->pool, m, ext);
     ap_str_tolower(enc);
-    apr_table_setn(m->encoding_types, ext, enc);
+    exinfo->encoding_type = enc;
     return NULL;
 }
 
@@ -230,12 +318,14 @@
 {
     mime_dir_config *m=m_;
     char *charset=apr_pstrdup(cmd->pool,charset_);
+    extension_info* exinfo;
 
     if (*ext == '.') {
     ++ext;
     }
+    exinfo = get_extension_info(cmd->pool, m, ext);
     ap_str_tolower(charset);
-    apr_table_setn(m->charset_types, ext, charset);
+    exinfo->charset_type = charset;
     return NULL;
 }
 
@@ -244,12 +334,14 @@
 {
     mime_dir_config *m=m_;
     char *lang=apr_pstrdup(cmd->pool,lang_);
+    extension_info* exinfo;
 
     if (*ext == '.') {
     ++ext;
     }
+    exinfo = get_extension_info(cmd->pool, m, ext);
     ap_str_tolower(lang);
-    apr_table_setn(m->language_types, ext, lang);
+    exinfo->language_type = lang;
     return NULL;
 }
 
@@ -258,11 +350,14 @@
 {
     mime_dir_config *m=m_;
     char *hdlr=apr_pstrdup(cmd->pool,hdlr_);
+    extension_info* exinfo;
 
-    if (*ext == '.')
+    if (*ext == '.') {
         ++ext;
+    }
+    exinfo = get_extension_info(cmd->pool, m, ext);
     ap_str_tolower(hdlr);
-    apr_table_setn(m->handlers, ext, hdlr);
+    exinfo->handler = hdlr;
     return NULL;
 }
 
@@ -279,6 +374,10 @@
     if (*ext == '.') {
         ++ext;
     }
+    if (mcfg->handlers_remove == NULL) {
+    mcfg->handlers_remove =
+        apr_array_make(cmd->pool, 4, sizeof(attrib_info));
+    }
     suffix = (attrib_info *) apr_array_push(mcfg->handlers_remove);
     suffix->name = apr_pstrdup(cmd->pool, ext);
     return NULL;
@@ -296,6 +395,10 @@
     if (*ext == '.') {
         ++ext;
     }
+    if (mcfg->encodings_remove == NULL) {
+    mcfg->encodings_remove =
+        apr_array_make(cmd->pool, 4, sizeof(attrib_info));
+    }
     suffix = (attrib_info *) apr_array_push(mcfg->encodings_remove);
     suffix->name = apr_pstrdup(cmd->pool, ext);
     return NULL;
@@ -313,6 +416,9 @@
     if (*ext == '.') {
         ++ext;
     }
+    if (mcfg->types_remove == NULL) {
+    mcfg->types_remove = apr_array_make(cmd->pool, 4, sizeof(attrib_info));
+    }
     suffix = (attrib_info *) apr_array_push(mcfg->types_remove);
     suffix->name = apr_pstrdup(cmd->pool, ext);
     return NULL;
@@ -361,16 +467,9 @@
      "language to use for documents with no other language file 
extension"),
     {NULL}
 };
-
-/* Hash apr_table_t  --- only one of these per daemon; virtual hosts can
- * get private versions through AddType...
- */
 
-#define MIME_HASHSIZE (32)
-#define hash(i) (apr_tolower(i) % MIME_HASHSIZE)
+static apr_hash_t *mime_type_extensions;
 
-static apr_table_t *hash_buckets[MIME_HASHSIZE];
-
 static void mime_post_config(apr_pool_t *p, apr_pool_t *plog, 
apr_pool_t *ptemp, server_rec *s)
 {
     ap_configfile_t *f;
@@ -390,8 +489,7 @@
         exit(1);
     }
 
-    for (x = 0; x < MIME_HASHSIZE; x++)
-        hash_buckets[x] = apr_table_make(p, 10);
+    mime_type_extensions = apr_hash_make(p);
 
     while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
         const char *ll = l, *ct;
@@ -403,7 +501,7 @@
         while (ll[0]) {
             char *ext = ap_getword_conf(p, &ll);
             ap_str_tolower(ext);   /* ??? */
-            apr_table_setn(hash_buckets[hash(ext[0])], ext, ct);
+        apr_hash_set(mime_type_extensions, ext, APR_HASH_KEY_STRING, ct);
         }
     }
     ap_cfg_closefile(f);
@@ -682,6 +780,7 @@
     /* Parse filename extensions, which can be in any order */
     while ((ext = ap_getword(r->pool, &fn, '.')) && *ext) {
         int found = 0;
+    extension_info *exinfo;
 
 #ifdef CASE_BLIND_FILESYSTEM
         /* We have a basic problem that folks on case-crippled systems
@@ -690,21 +789,25 @@
         ap_str_tolower(ext);
 #endif
 
+    exinfo = (extension_info*) apr_hash_get(conf->extension_mappings,
+                        ext, APR_HASH_KEY_STRING);
+
         /* Check for Content-Type */
-        if ((type = apr_table_get(conf->forced_types, ext))
-            || (type = apr_table_get(hash_buckets[hash(*ext)], ext))) {
+        if ((exinfo && ((type = exinfo->forced_type)))
+            || (type = apr_hash_get(mime_type_extensions, ext,
+                    APR_HASH_KEY_STRING))) {
             r->content_type = type;
             found = 1;
         }
 
     /* Add charset to Content-Type */
-    if ((type = apr_table_get(conf->charset_types, ext))) {
+    if (exinfo && ((type = exinfo->charset_type))) {
         charset = type;
         found = 1;
     }
 
         /* Check for Content-Language */
-        if ((type = apr_table_get(conf->language_types, ext))) {
+        if (exinfo && ((type = exinfo->language_type))) {
             const char **new;
 
             r->content_language = type;         /* back compat. only */
@@ -716,7 +819,7 @@
         }
 
         /* Check for Content-Encoding */
-        if ((type = apr_table_get(conf->encoding_types, ext))) {
+        if (exinfo && ((type = exinfo->encoding_type))) {
             if (!r->content_encoding)
                 r->content_encoding = type;
             else
@@ -726,9 +829,8 @@
         }
 
         /* Check for a special handler, but not for proxy request */
-        if ((type = apr_table_get(conf->handlers, ext))
-        && (PROXYREQ_NONE == r->proxyreq)
-        ) {
+        if ((exinfo && ((type = exinfo->handler)))
+        && (PROXYREQ_NONE == r->proxyreq)) {
             r->handler = type;
             found = 1;
         }



Re: [PATCH] mod_mime performance tweaks, revised

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
From: "Brian Pane" <bp...@pacbell.net>
Sent: Monday, August 06, 2001 10:13 PM


> William A. Rowe, Jr. wrote:
> 
> >From: "Brian Pane" <bp...@pacbell.net>
> >Sent: Monday, August 06, 2001 4:51 PM
> >
> >
> >>The patch in question got committed a long time ago, back in version
> >>1.43 of mod_mime.c.  I checked the current rev in CVS, and it's still
> >>using the hash tables that my patch introduced.
> >>
> >
> >Ahhh.  I thought you offered a further patch to allow just segments of the filename
> >to be matched, so that index.en would match index.html.en.  I must have been imagining
> >things :)
> 
> I bet you're thinking of the patch I posted to optimize away the
> ap_getword calls in mod_mime (which wasn't committed).  That
> one definitely won't work with the latest mod_mime code.  I'll
> see if I can do the same optimization (replace ap_getword with
> inline string-scanning to eliminate some string-copying) against
> the current code base; if it works, I'll post a patch.

Actually, once updated, it will work better.  It can solve the tangle of index.html.unk.en
not being served when the user requests index.html.unk because it can recognize that the
user asked for both index and unk.  Right now, it strcmp's index.unk (the unknown bits)
to index.html.unk, and will die.

If it makes the original patch simpler/lighter, I do insist we will only parse elements
forward, so a request for index.html.en can't return index.en.html (two very different
names.)  If we can agree on that, your patch should be very fast :)

Bill


Re: [PATCH] mod_mime performance tweaks, revised

Posted by Brian Pane <bp...@pacbell.net>.
William A. Rowe, Jr. wrote:

>From: "Brian Pane" <bp...@pacbell.net>
>Sent: Monday, August 06, 2001 4:51 PM
>
>
>>The patch in question got committed a long time ago, back in version
>>1.43 of mod_mime.c.  I checked the current rev in CVS, and it's still
>>using the hash tables that my patch introduced.
>>
>
>Ahhh.  I thought you offered a further patch to allow just segments of the filename
>to be matched, so that index.en would match index.html.en.  I must have been imagining
>things :)
>
I bet you're thinking of the patch I posted to optimize away the
ap_getword calls in mod_mime (which wasn't committed).  That
one definitely won't work with the latest mod_mime code.  I'll
see if I can do the same optimization (replace ap_getword with
inline string-scanning to eliminate some string-copying) against
the current code base; if it works, I'll post a patch.

--Brian


Re: [PATCH] mod_mime performance tweaks, revised

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
From: "Brian Pane" <bp...@pacbell.net>
Sent: Monday, August 06, 2001 4:51 PM


> The patch in question got committed a long time ago, back in version
> 1.43 of mod_mime.c.  I checked the current rev in CVS, and it's still
> using the hash tables that my patch introduced.

Ahhh.  I thought you offered a further patch to allow just segments of the filename
to be matched, so that index.en would match index.html.en.  I must have been imagining
things :)

Bill

> William A. Rowe, Jr. wrote:
> 
> >  I won't have much time until next Tuesday, but I'd be happy to review and then
> >commit the idea, based on a couple of significant restrictions;
> >
> >1. the order of suffixes _must_ remain constant.
> >   That is, if the user asks for something.html.en, they cannot be served 
> >   something.en.html.  If they ask for simply something, something.html, or
> >   something.en, I'd be happy if we serve something.html.en or something.en.html
> >   based on negotation (if they both existed, the smaller would win.)
> >
> >2. the negotation exception-list code needs to be changed to check the exceptions
> >   list one segment at a time against the segments the user requested, also in the 
> >   same sequence.  So asking for index.bak might return index.html.en.bak, or even
> >   index.bak.html.en, but asking for index.html can _never_ find index.bak since
> >   the .bak extension isn't recognized by mod_mime.
> >
> >  So if you will fix the patch against these requirements, I'm +1, and will review
> >and commit if nobody objects, sometime early next week (cc wrowe at rowe-clan.net so
> >it ends up on my priority stack, I'll be catching up on a ton of email Monday.)
> >
> >Bill
> >
> >
> >
> 
> 
> 
> 


Re: [PATCH] mod_mime performance tweaks, revised

Posted by Brian Pane <bp...@pacbell.net>.
The patch in question got committed a long time ago, back in version
1.43 of mod_mime.c.  I checked the current rev in CVS, and it's still
using the hash tables that my patch introduced.

--Brian

William A. Rowe, Jr. wrote:

>From: "Brian Pane" <bp...@pacbell.net>
>Sent: Wednesday, June 27, 2001 11:50 AM
>
>
>>I've revised my mod_mime optimization patch a bit
>>to try to speed up the merge-per-dir-config implementation.
>>This patch replaces the previous one that I posted.  (That's the
>>last of my changes, I promise, until somebody reviews this
>>one :-)
>>
>
>Brian,
>
>  As you can guess, the recent mime and negotation fixes entirely broke this patch :(
>
>  I won't have much time until next Tuesday, but I'd be happy to review and then
>commit the idea, based on a couple of significant restrictions;
>
>1. the order of suffixes _must_ remain constant.
>   That is, if the user asks for something.html.en, they cannot be served 
>   something.en.html.  If they ask for simply something, something.html, or
>   something.en, I'd be happy if we serve something.html.en or something.en.html
>   based on negotation (if they both existed, the smaller would win.)
>
>2. the negotation exception-list code needs to be changed to check the exceptions
>   list one segment at a time against the segments the user requested, also in the 
>   same sequence.  So asking for index.bak might return index.html.en.bak, or even
>   index.bak.html.en, but asking for index.html can _never_ find index.bak since
>   the .bak extension isn't recognized by mod_mime.
>
>  So if you will fix the patch against these requirements, I'm +1, and will review
>and commit if nobody objects, sometime early next week (cc wrowe at rowe-clan.net so
>it ends up on my priority stack, I'll be catching up on a ton of email Monday.)
>
>Bill
>
>
>




Re: [PATCH] mod_mime performance tweaks, revised

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
From: "Brian Pane" <bp...@pacbell.net>
Sent: Wednesday, June 27, 2001 11:50 AM


> I've revised my mod_mime optimization patch a bit
> to try to speed up the merge-per-dir-config implementation.
> This patch replaces the previous one that I posted.  (That's the
> last of my changes, I promise, until somebody reviews this
> one :-)

Brian,

  As you can guess, the recent mime and negotation fixes entirely broke this patch :(

  I won't have much time until next Tuesday, but I'd be happy to review and then
commit the idea, based on a couple of significant restrictions;

1. the order of suffixes _must_ remain constant.
   That is, if the user asks for something.html.en, they cannot be served 
   something.en.html.  If they ask for simply something, something.html, or
   something.en, I'd be happy if we serve something.html.en or something.en.html
   based on negotation (if they both existed, the smaller would win.)

2. the negotation exception-list code needs to be changed to check the exceptions
   list one segment at a time against the segments the user requested, also in the 
   same sequence.  So asking for index.bak might return index.html.en.bak, or even
   index.bak.html.en, but asking for index.html can _never_ find index.bak since
   the .bak extension isn't recognized by mod_mime.

  So if you will fix the patch against these requirements, I'm +1, and will review
and commit if nobody objects, sometime early next week (cc wrowe at rowe-clan.net so
it ends up on my priority stack, I'll be catching up on a ton of email Monday.)

Bill



Re: [PATCH] mod_mime performance tweaks, revised

Posted by Brian Pane <bp...@pacbell.net>.
dean gaudet wrote:

>On Wed, 27 Jun 2001, Brian Pane wrote:
>
>>+/* Information to which an extension can be mapped
>>+ */
>>+typedef struct extension_info {
>>+    char *forced_type;                /* Additional AddTyped stuff */
>>+    char *encoding_type;              /* Added with AddEncoding... */
>>+    char *language_type;              /* Added with AddLanguage... */
>>+    char *handler;                    /* Added with AddHandler... */
>>+    char *charset_type;               /* Added with AddCharset... */
>>+} extension_info;
>>+
>>
>
>looks like you're causing the data structure to use a fair amount more
>memory ... or at least spreading out the data onto more cache lines.
>you've got 5 pointers per extension when only 1 is typically needed right?
>
Right--the code is intentionally sacrificing some memory to gain speed.
In the original,  there were 5 tables, and each extension was looked up
in each table on each request (and most of these lookups typically yielded
no match).  In my patch, there's a single lookup that retrieves the 
extension_info
structure (in which most of the fields are NULL, but retrieving a field 
value
from the struct is cheap compared to the hash table lookup).

--Brian

>
>an alternative is to make the "extension info" part of the key to the hash
>table.  so rather than just using the extension to look up an
>extension_info and then extract the pointer field_name, you use
>(extension, field_name) to look up a pointer.
>
>you could do this by prepending some constant to the extension, like "0" =
>forced_type, "1"  = encoding_type, ...
>
>(or perhaps APR hash tables are generic enough that you can use different
>keys other than strings, i haven't looked.)
>
>-dean
>
>
>




Re: [PATCH] mod_mime performance tweaks, revised

Posted by dean gaudet <dg...@arctic.org>.
On Wed, 27 Jun 2001, Brian Pane wrote:

> +/* Information to which an extension can be mapped
> + */
> +typedef struct extension_info {
> +    char *forced_type;                /* Additional AddTyped stuff */
> +    char *encoding_type;              /* Added with AddEncoding... */
> +    char *language_type;              /* Added with AddLanguage... */
> +    char *handler;                    /* Added with AddHandler... */
> +    char *charset_type;               /* Added with AddCharset... */
> +} extension_info;
> +

looks like you're causing the data structure to use a fair amount more
memory ... or at least spreading out the data onto more cache lines.
you've got 5 pointers per extension when only 1 is typically needed right?

an alternative is to make the "extension info" part of the key to the hash
table.  so rather than just using the extension to look up an
extension_info and then extract the pointer field_name, you use
(extension, field_name) to look up a pointer.

you could do this by prepending some constant to the extension, like "0" =
forced_type, "1"  = encoding_type, ...

(or perhaps APR hash tables are generic enough that you can use different
keys other than strings, i haven't looked.)

-dean