]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: Track list of hosts using a linked list also.
authorTimo Sirainen <tss@iki.fi>
Tue, 26 Feb 2013 11:03:30 +0000 (13:03 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 26 Feb 2013 11:03:30 +0000 (13:03 +0200)
http_client_switch_ioloop() is done very often, and scanning a few entries
in a linked list is much faster than going through a hash table.

src/lib-http/http-client-host.c
src/lib-http/http-client-private.h
src/lib-http/http-client.c

index f9cba136902df755a44ecdb736fa5e635c21817f..883e43152acf3abf52f9e861964b9ee1dca9dec1 100644 (file)
@@ -5,6 +5,7 @@
 #include "str.h"
 #include "hash.h"
 #include "array.h"
+#include "llist.h"
 #include "ioloop.h"
 #include "istream.h"
 #include "ostream.h"
@@ -276,6 +277,7 @@ struct http_client_host *http_client_host_get
 
                hostname = host->name;
                hash_table_insert(client->hosts, hostname, host);
+               DLLIST_PREPEND(&client->hosts_list, host);
 
                http_client_host_debug(host, "Host created");
        }
@@ -367,9 +369,13 @@ void http_client_host_free(struct http_client_host **_host)
 {
        struct http_client_host *host = *_host;
        struct http_client_host_port *hport;
+       const char *hostname = host->name;
 
        http_client_host_debug(host, "Host destroy");
 
+       DLLIST_REMOVE(&host->client->hosts_list, host);
+       hash_table_remove(host->client->hosts, hostname);
+
        if (host->dns_lookup != NULL)
                dns_lookup_abort(&host->dns_lookup);
 
index 4edb50914988ca096c2cb55e101dfec43e0e6f15..d599aa6ff6ec6c7ffd6bc163d9b5e1b360ea7809 100644 (file)
@@ -94,6 +94,8 @@ struct http_client_host_port {
 };
 
 struct http_client_host {
+       struct http_client_host *prev, *next;
+
        struct http_client *client;
        char *name;
 
@@ -175,6 +177,7 @@ struct http_client {
        struct connection_list *conn_list;
 
        HASH_TABLE_TYPE(http_client_host) hosts;
+       struct http_client_host *hosts_list;
        HASH_TABLE_TYPE(http_client_peer) peers;
        unsigned int pending_requests;
 };
index c55191c4e257230d44877f9eaabff32e35ea0236..19e3f55e9cb73196e297787f5f35d5e9d9c759dd 100644 (file)
@@ -104,7 +104,6 @@ void http_client_deinit(struct http_client **_client)
 {
        struct http_client *client = *_client;
        struct hash_iterate_context *iter;
-       const char *hostname;
        struct http_client_host *host;
        const struct http_client_peer_addr *addr;
        struct http_client_peer *peer;
@@ -118,11 +117,10 @@ void http_client_deinit(struct http_client **_client)
        hash_table_destroy(&client->peers);
 
        /* free hosts */
-       iter = hash_table_iterate_init(client->hosts);
-       while (hash_table_iterate(iter, client->hosts, &hostname, &host)) {
+       while (client->hosts_list != NULL) {
+               host = client->hosts_list;
                http_client_host_free(&host);
        }
-       hash_table_iterate_deinit(&iter);
        hash_table_destroy(&client->hosts);
 
        connection_list_deinit(&client->conn_list);
@@ -147,15 +145,10 @@ void http_client_switch_ioloop(struct http_client *client)
 
        /* move dns lookups */
        if (client->set.dns_client_socket_path != '\0') {
-               struct hash_iterate_context *iter;
                struct http_client_host *host;
-               const char *hostname;
        
-               iter = hash_table_iterate_init(client->hosts);
-               while (hash_table_iterate(iter, client->hosts, &hostname, &host)) {
+               for (host = client->hosts_list; host != NULL; host = host->next)
                        http_client_host_switch_ioloop(host);
-               }
-               hash_table_iterate_deinit(&iter);
        }
 }