From 4c59c0cfdc1882b6571272035e66223a8068ecfa Mon Sep 17 00:00:00 2001 From: Justin Erenkrantz Date: Tue, 4 Sep 2001 06:50:52 +0000 Subject: [PATCH] The ap_add_input_filter/ap_add_output_filter functions do an O(n) scan through the list of registered filters. This patch replaces the linear list with a hash table for better performance. Submitted by: Brian Pane Reviewed by: Justin Erenkrantz git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90888 13f79535-47bb-0310-9956-ffa450edef68 --- server/util_filter.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/server/util_filter.c b/server/util_filter.c index 3735632db1..4ae809c38f 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -54,16 +54,18 @@ #define APR_WANT_STRFUNC #include "apr_want.h" +#include "apr_lib.h" +#include "apr_hash.h" +#include "apr_strings.h" #include "httpd.h" #include "http_log.h" #include "util_filter.h" /* ### make this visible for direct manipulation? - * ### use a hash table */ -static ap_filter_rec_t *registered_output_filters = NULL; -static ap_filter_rec_t *registered_input_filters = NULL; +static apr_hash_t *registered_output_filters = NULL; +static apr_hash_t *registered_input_filters = NULL; /* NOTE: Apache's current design doesn't allow a pool to be passed thu, so we depend on a global to hold the correct pool @@ -92,16 +94,20 @@ static apr_status_t filter_cleanup(void *ctx) static void register_filter(const char *name, ap_filter_func filter_func, ap_filter_type ftype, - ap_filter_rec_t **reg_filter_list) + apr_hash_t **reg_filter_set) { ap_filter_rec_t *frec = apr_palloc(FILTER_POOL, sizeof(*frec)); - frec->name = name; + if (!*reg_filter_set) { + *reg_filter_set = apr_hash_make(FILTER_POOL); + } + + frec->name = apr_pstrdup(FILTER_POOL, name); + ap_str_tolower((char *)frec->name); frec->filter_func = filter_func; frec->ftype = ftype; - frec->next = *reg_filter_list; - *reg_filter_list = frec; + apr_hash_set(*reg_filter_set, frec->name, APR_HASH_KEY_STRING, frec); apr_pool_cleanup_register(FILTER_POOL, NULL, filter_cleanup, apr_pool_cleanup_null); } @@ -126,12 +132,26 @@ AP_DECLARE(void) ap_register_output_filter(const char *name, static ap_filter_t *add_any_filter(const char *name, void *ctx, request_rec *r, conn_rec *c, - ap_filter_rec_t *frec, + apr_hash_t *reg_filter_set, ap_filter_t **r_filters, ap_filter_t **c_filters) { - for (; frec != NULL; frec = frec->next) { - if (!strcasecmp(name, frec->name)) { + if (reg_filter_set) { + ap_filter_rec_t *frec; + int len = strlen(name); + int size = len + 1; + char name_lower[size]; + char *dst = name_lower; + const char *src = name; + + /* Normalize the name to all lowercase to match register_filter() */ + do { + *dst++ = apr_tolower(*src++); + } while (--size); + + frec = (ap_filter_rec_t *)apr_hash_get(reg_filter_set, + name_lower, len); + if (frec) { apr_pool_t *p = r ? r->pool : c->pool; ap_filter_t *f = apr_pcalloc(p, sizeof(*f)); ap_filter_t **outf = r ? r_filters : c_filters; -- 2.40.0