diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2012-01-11 22:00:48 +0000 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2012-01-11 22:00:48 +0000 |
commit | 915363f976064224958985f2a4b090c668d9fe9f (patch) | |
tree | 112785a2f5c6cc052c48e10a386ead3fb433b662 | |
parent | 205fafa57767db68a0fb810616d1756a4ce2a1e4 (diff) | |
download | dnsmasq-2.60test9.tar.gz |
Tweaks to hostfile performance work.v2.60test9
-rw-r--r-- | src/cache.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/src/cache.c b/src/cache.c index 0ad0c43..59c4ffc 100644 --- a/src/cache.c +++ b/src/cache.c @@ -660,9 +660,7 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl whilst reading hosts files: the buckets are then freed, and the ->next pointer used for other things. - We search and bail at the first matching address that came from - a HOSTS file. Since the first host entry gets reverse, we know - then that it must exist without searching exhaustively for it. + Only insert each unique address one into this hashing structure. This complexity avoids O(n^2) divergent CPU use whilst reading large (10000 entry) hosts files. */ @@ -671,7 +669,9 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl for (j = 0, i = 0; i < addrlen; i++) j += ((unsigned char *)addr)[i] + (j << 6) + (j << 16) - j; - for (lookup = rhash[j % RHASHSIZE]; lookup; lookup = lookup->next) + j = j % RHASHSIZE; + + for (lookup = rhash[j]; lookup; lookup = lookup->next) if ((lookup->flags & F_HOSTS) && (lookup->flags & flags & (F_IPV4 | F_IPV6)) && memcmp(&lookup->addr.addr, addr, addrlen) == 0) @@ -680,15 +680,16 @@ static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrl break; } + /* maintain address hash chain, insert new unique address */ + if (!lookup) + { + cache->next = rhash[j]; + rhash[j] = cache; + } + cache->flags = flags; cache->uid = index; - - /* maintain address has chain */ - cache->next = rhash[j % RHASHSIZE]; - rhash[j % RHASHSIZE] = cache; - - memcpy(&cache->addr.addr, addr, addrlen); - + memcpy(&cache->addr.addr, addr, addrlen); cache_hash(cache); /* don't need to do alias stuff for second and subsequent addresses. */ |