From: Brian Pane Date: Mon, 31 Dec 2001 08:18:32 +0000 (+0000) Subject: Performance fix for prep_walk_cache(): X-Git-Tag: 2.0.30~60 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=199e4864fc9ce12e7d22fba8c3c0ee39ab9e6879;p=apache Performance fix for prep_walk_cache(): Moved the directory/location/file-walk caches from the request's pool userdata hash table to the core_request_config struct. This change removes about 60% of the processing time from prep_walk_cache(). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92684 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_core.h b/include/http_core.h index a6964179b9..2c8bfb8525 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -330,10 +330,21 @@ AP_DECLARE_DATA extern module core_module; /* Per-request configuration */ +typedef enum { + AP_WALK_DIRECTORY, + AP_WALK_LOCATION, + AP_WALK_FILE, + AP_NUM_WALK_CACHES +} ap_walk_cache_type; + typedef struct { /* bucket brigade used by getline for look-ahead and * ap_get_client_block for holding left-over request body */ struct apr_bucket_brigade *bb; + + /* a place to hold per-request working data for + * ap_directory_walk, ap_location_walk, and ap_file_walk */ + void *walk_cache[AP_NUM_WALK_CACHES]; } core_request_config; /* Per-directory configuration */ diff --git a/server/core.c b/server/core.c index 12d6a6bfa3..c3924d5d08 100644 --- a/server/core.c +++ b/server/core.c @@ -3385,17 +3385,18 @@ static void core_insert_filter(request_rec *r) static int core_create_req(request_rec *r) { + core_request_config *req_cfg; + req_cfg = apr_palloc(r->pool, sizeof(core_request_config)); + memset(req_cfg, 0, sizeof(*req_cfg)); if (r->main) { - ap_set_module_config(r->request_config, &core_module, - ap_get_module_config(r->main->request_config, &core_module)); + core_request_config *main_req_cfg = (core_request_config *) + ap_get_module_config(r->main->request_config, &core_module); + req_cfg->bb = main_req_cfg->bb; } else { - core_request_config *req_cfg; - - req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config)); req_cfg->bb = apr_brigade_create(r->pool); - ap_set_module_config(r->request_config, &core_module, req_cfg); } + ap_set_module_config(r->request_config, &core_module, req_cfg); ap_add_input_filter("NET_TIME", NULL, r, r->connection); diff --git a/server/request.c b/server/request.c index 34a2788d5d..dd35e88c19 100644 --- a/server/request.c +++ b/server/request.c @@ -296,9 +296,10 @@ typedef struct walk_cache_t { apr_array_header_t *walked; /* The list of walk_walked_t results */ } walk_cache_t; -static walk_cache_t *prep_walk_cache(const char *cache_name, request_rec *r) +static walk_cache_t *prep_walk_cache(ap_walk_cache_type t, request_rec *r) { walk_cache_t *cache; + core_request_config *my_req_cfg; /* Find the most relevant, recent entry to work from. That would be * this request (on the second call), or the parent request of a @@ -306,25 +307,30 @@ static walk_cache_t *prep_walk_cache(const char *cache_name, request_rec *r) * this _walk()er with a copy it is allowed to munge. If there is no * parent or prior cached request, then create a new walk cache. */ - if ((apr_pool_userdata_get((void **)&cache, cache_name, r->pool) - != APR_SUCCESS) - || !cache) { - if ((r->main && (apr_pool_userdata_get((void **)&cache, - cache_name, - r->main->pool) - == APR_SUCCESS) && cache) - || (r->prev && (apr_pool_userdata_get((void **)&cache, - cache_name, - r->prev->pool) - == APR_SUCCESS) && cache)) { - cache = apr_pmemdup(r->pool, cache, sizeof(*cache)); + my_req_cfg = (core_request_config *) + ap_get_module_config(r->request_config, &core_module); + + if (!my_req_cfg || !(cache = my_req_cfg->walk_cache[t])) { + core_request_config *req_cfg; + if ((r->main && + (req_cfg = (core_request_config *) + ap_get_module_config(r->main->request_config, &core_module)) && + req_cfg->walk_cache[t]) || + (r->prev && + (req_cfg = (core_request_config *) + ap_get_module_config(r->prev->request_config, &core_module)) && + req_cfg->walk_cache[t])) { + cache = apr_pmemdup(r->pool, req_cfg->walk_cache[t], + sizeof(*cache)); cache->walked = apr_array_copy(r->pool, cache->walked); } else { cache = apr_pcalloc(r->pool, sizeof(*cache)); cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t)); } - apr_pool_userdata_setn(cache, cache_name, NULL, r->pool); + if (my_req_cfg) { + my_req_cfg->walk_cache[t] = cache; + } } return cache; } @@ -483,7 +489,7 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) */ r->filename = entry_dir; - cache = prep_walk_cache("ap_directory_walk::cache", r); + cache = prep_walk_cache(AP_WALK_DIRECTORY, r); /* If this is not a dirent subrequest with a preconstructed * r->finfo value, then we can simply stat the filename to @@ -1057,7 +1063,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) walk_cache_t *cache; const char *entry_uri; - cache = prep_walk_cache("ap_location_walk::cache", r); + cache = prep_walk_cache(AP_WALK_LOCATION, r); /* No tricks here, there are no to parse in this vhost. * We won't destroy the cache, just in case _this_ redirect is later @@ -1213,7 +1219,7 @@ AP_DECLARE(int) ap_file_walk(request_rec *r) return OK; } - cache = prep_walk_cache("ap_file_walk::cache", r); + cache = prep_walk_cache(AP_WALK_FILE, r); /* No tricks here, there are just no to parse in this context. * We won't destroy the cache, just in case _this_ redirect is later