From: Arjan van de Ven Date: Tue, 10 Jan 2012 00:08:49 +0000 (-0800) Subject: dnsproxy: Deal nicer with a cache-full situation X-Git-Tag: 2.0_alpha~728 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=475c2450978e5354370756402b4f88e58c84f30a;p=framework%2Fconnectivity%2Fconnman.git dnsproxy: Deal nicer with a cache-full situation Now that we have hit counts for the cache, we can make the cache-full handling slightly smarter; if we can't make space freeing expired entries, we can now make space freeing entries that have a very low use count. --- diff --git a/src/dnsproxy.c b/src/dnsproxy.c index d2fa07c..730b033 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -938,6 +938,7 @@ out: struct cache_timeout { time_t current_time; int max_timeout; + int try_harder; }; static gboolean cache_check_entry(gpointer key, gpointer value, @@ -947,6 +948,10 @@ static gboolean cache_check_entry(gpointer key, gpointer value, struct cache_entry *entry = value; int max_timeout; + /* Scale the number of hits by half as part of cache aging */ + + entry->hits /= 2; + /* * If either IPv4 or IPv6 cached entry has expired, we * remove both from the cache. @@ -970,6 +975,13 @@ static gboolean cache_check_entry(gpointer key, gpointer value, return TRUE; } + /* + * if we're asked to try harder, also remove entries that have + * few hits + */ + if (data->try_harder && entry->hits < 4) + return TRUE; + return FALSE; } @@ -977,20 +989,32 @@ static void cache_cleanup(void) { static int max_timeout; struct cache_timeout data; - int count; + int count = 0; data.current_time = time(0); data.max_timeout = 0; + data.try_harder = 0; - if (max_timeout > data.current_time) { - DBG("waiting %ld secs before cleaning cache", - max_timeout - data.current_time); - return; + /* + * In the first pass, we only remove entries that have timed out. + * We use a cache of the first time to expire to do this only + * when it makes sense. + */ + if (max_timeout <= data.current_time) { + count = g_hash_table_foreach_remove(cache, cache_check_entry, + &data); } + DBG("removed %d in the first pass", count); - count = g_hash_table_foreach_remove(cache, cache_check_entry, + /* + * In the second pass, if the first pass turned up blank, + * we also expire entries with a low hit count, + * while aging the hit count at the same time. + */ + data.try_harder = 1; + if (count == 0) + count = g_hash_table_foreach_remove(cache, cache_check_entry, &data); - DBG("removed %d", count); if (count == 0) /*