]>
Commit | Line | Data |
---|---|---|
63a80378 AM |
1 | commit 813fdb4c8e2fc02cf4c5738e46b204f28d0763a3 |
2 | Author: sf <sf@13f79535-47bb-0310-9956-ffa450edef68> | |
3 | Date: Sat Oct 2 14:44:20 2010 +0000 | |
4 | ||
5 | core: Speed up config parsing if using a very large number of config | |
6 | files | |
7 | ||
8 | PR: 50002 | |
9 | Submitted by: andrew cloudaccess net | |
10 | ||
11 | ||
12 | git-svn-id: http://svn.apache.org/repos/asf/httpd/httpd/trunk@1003808 13f79535-47bb-0310-9956-ffa450edef68 | |
13 | ||
63a80378 AM |
14 | diff --git a/include/util_cfgtree.h b/include/util_cfgtree.h |
15 | index 4da4c7d..791a5cc 100644 | |
16 | --- a/include/util_cfgtree.h | |
17 | +++ b/include/util_cfgtree.h | |
18 | @@ -64,6 +64,13 @@ struct ap_directive_t { | |
19 | const char *filename; | |
20 | /** The line number the directive was on */ | |
21 | int line_num; | |
22 | + | |
23 | + /** A short-cut towards the last directive node in the tree. | |
24 | + * The value may not always be up-to-date but it always points to | |
25 | + * somewhere in the tree, nearer to the tail. | |
26 | + * This value is only set in the first node | |
27 | + */ | |
28 | + struct ap_directive_t *last; | |
29 | }; | |
30 | ||
31 | /** | |
32 | diff --git a/server/config.c b/server/config.c | |
33 | index dc9b3b6..a3d67f0 100644 | |
34 | --- a/server/config.c | |
35 | +++ b/server/config.c | |
36 | @@ -1284,11 +1284,30 @@ AP_DECLARE(const char *) ap_build_config(cmd_parms *parms, | |
37 | ap_directive_t *curr_parent = NULL; | |
38 | char *l = apr_palloc (temp_pool, MAX_STRING_LEN); | |
39 | const char *errmsg; | |
40 | + ap_directive_t **last_ptr = NULL; | |
41 | + | |
42 | + if(current) { | |
43 | + /* If we have to traverse the whole tree again for every included | |
44 | + * config file, the required time grows as O(n^2) with the number of | |
45 | + * files. This can be a significant delay for large configurations. | |
46 | + * Therefore we cache a pointer to the last node. | |
47 | + */ | |
48 | + last_ptr = &(current->last); | |
49 | + | |
50 | + if(last_ptr && *last_ptr) { | |
51 | + current = *last_ptr; | |
52 | + } | |
53 | + } | |
54 | ||
55 | if (current != NULL) { | |
56 | while (current->next) { | |
57 | current = current->next; | |
58 | } | |
59 | + | |
60 | + if(last_ptr) { | |
61 | + /* update cached pointer to last node */ | |
62 | + *last_ptr = current; | |
63 | + } | |
64 | } | |
65 | ||
66 | while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) { |