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/09/04 07:50:01 UTC
[PATCH] hash table for registered filter list
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.
--Brian
Index: server/util_filter.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/util_filter.c,v
retrieving revision 1.65
diff -u -r1.65 util_filter.c
--- server/util_filter.c 2001/08/30 05:25:31 1.65
+++ server/util_filter.c 2001/09/04 05:42:17
@@ -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,21 @@
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 = NULL;
- 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 +133,26 @@
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;