mirror of
https://github.com/apache/httpd.git
synced 2025-08-10 02:56:11 +00:00
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
This commit is contained in:
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <Locations > 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 <Files > to parse in this context.
|
||||
* We won't destroy the cache, just in case _this_ redirect is later
|
||||
|
Reference in New Issue
Block a user