summaryrefslogtreecommitdiff
path: root/src/dnsproxy.c
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2012-01-09 16:08:49 -0800
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-10 13:43:57 +0100
commit475c2450978e5354370756402b4f88e58c84f30a (patch)
tree9655c7c89a8eb2f2304e910d088ee15a37415479 /src/dnsproxy.c
parentce243d289f022921d21168e3682abe5d6f901340 (diff)
downloadconnman-475c2450978e5354370756402b4f88e58c84f30a.tar.gz
connman-475c2450978e5354370756402b4f88e58c84f30a.tar.bz2
connman-475c2450978e5354370756402b4f88e58c84f30a.zip
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.
Diffstat (limited to 'src/dnsproxy.c')
-rw-r--r--src/dnsproxy.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index d2fa07cb..730b0333 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)
/*