diff options
author | Steinar H. Gunderson <sesse@google.com> | 2007-09-29 18:18:47 +0000 |
---|---|---|
committer | Steinar H. Gunderson <sesse@google.com> | 2007-09-29 18:18:47 +0000 |
commit | 04e49e09dcfac29e7e90b5546672a9b42d0b935a (patch) | |
tree | 82057cf2db538d1d8682daad0623ea330812a042 /ares_init.c | |
parent | edf19010776aee7913d5866ed290349f5b333251 (diff) | |
download | c-ares-04e49e09dcfac29e7e90b5546672a9b42d0b935a.tar.gz c-ares-04e49e09dcfac29e7e90b5546672a9b42d0b935a.tar.bz2 c-ares-04e49e09dcfac29e7e90b5546672a9b42d0b935a.zip |
Previously, processing a large batch of timeouts was O(n^2) in the number of
outstanding queries, and processing a DNS response packet was O(n) in the
number of outstanding queries. To speed things up in Google, we added a few circular,
doubly-linked lists of queries that are hash-bucketed based on
the attributes we care about, so most important operations are now O(1).
It might be that the number of buckets are higher than most people would need,
but on a quick calculation it should only be 100kB or so even on a 64-bit
system, so I've let it stay as-is.
Diffstat (limited to 'ares_init.c')
-rw-r--r-- | ares_init.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/ares_init.c b/ares_init.c index 6c36d6e..c792f0a 100644 --- a/ares_init.c +++ b/ares_init.c @@ -107,6 +107,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, int i; int status = ARES_SUCCESS; struct server_state *server; + struct timeval tv; #ifdef CURLDEBUG const char *env = getenv("CARES_MEMDEBUG"); @@ -140,13 +141,26 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, channel->nsort = -1; channel->tcp_connection_generation = 0; channel->lookups = NULL; - channel->queries = NULL; channel->domains = NULL; channel->sortlist = NULL; channel->servers = NULL; channel->sock_state_cb = NULL; channel->sock_state_cb_data = NULL; + gettimeofday(&tv, NULL); + channel->last_timeout_processed = tv.tv_sec; + + /* Initialize our lists of queries */ + ares__init_list_head(&(channel->all_queries)); + for (i = 0; i < ARES_QID_TABLE_SIZE; i++) + { + ares__init_list_head(&(channel->queries_by_qid[i])); + } + for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) + { + ares__init_list_head(&(channel->queries_by_timeout[i])); + } + /* Initialize configuration by each of the four sources, from highest * precedence to lowest. */ @@ -209,13 +223,14 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, server->tcp_buffer = NULL; server->qhead = NULL; server->qtail = NULL; + ares__init_list_head(&(server->queries_to_server)); + server->channel = channel; server->is_broken = 0; } init_id_key(&channel->id_key, ARES_ID_KEY_LEN); channel->next_id = ares__generate_new_id(&channel->id_key); - channel->queries = NULL; *channelptr = channel; return ARES_SUCCESS; |