From 9070c743a258987674aefc2c24415c436a00f08e Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 28 Mar 2007 08:38:02 +0200 Subject: [PATCH] network plugin: Implemented cache flush. --- src/collectd.conf.in | 1 + src/collectd.conf.pod | 10 ++++++ src/network.c | 73 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 2b349468..d1614b79 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -127,6 +127,7 @@ # Listen "239.192.74.66" "25826" # TimeToLive "128" # Forward false +# CacheFlush 1800 # # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 02e6def1..98612dce 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -379,6 +379,16 @@ the same multicast group. While this results in more network traffic than neccessary it's not a huge problem since the plugin has a duplicate detection, so the values will not loop. +=item B I + +For each host/plugin/type combination the C caches the time of +the last value being sent or received. Every I seconds the plugin +searches and removes all entries that are older than I seconds, thus +freeing the unused memory again. Since this process is somewhat expensive and +normally doesn't do much, this value should not be too small. The default is +1800 seconds, but setting this to 86400 seconds (one day) will not do much harm +either. + =back =head2 Plugin C diff --git a/src/network.c b/src/network.c index 96d48f8b..6d86c1d0 100644 --- a/src/network.c +++ b/src/network.c @@ -141,6 +141,7 @@ typedef struct part_values_s part_values_t; */ static const char *config_keys[] = { + "CacheFlush", "Listen", "Server", "TimeToLive", @@ -167,10 +168,69 @@ static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; static avl_tree_t *cache_tree = NULL; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; +static time_t cache_flush_last; +static int cache_flush_interval = 1800; /* * Private functions */ +static int cache_flush (void) +{ + char **keys = NULL; + int keys_num = 0; + + char **tmp; + int i; + + char *key; + time_t *value; + avl_iterator_t *iter; + + time_t curtime = time (NULL); + + iter = avl_get_iterator (cache_tree); + while (avl_iterator_next (iter, (void *) &key, (void *) &value) == 0) + { + if ((curtime - *value) <= cache_flush_interval) + continue; + tmp = (char **) realloc (keys, + (keys_num + 1) * sizeof (char *)); + if (tmp == NULL) + { + sfree (keys); + avl_iterator_destroy (iter); + ERROR ("network plugin: cache_flush: realloc" + " failed."); + return (-1); + } + keys = tmp; + keys[keys_num] = key; + keys_num++; + } /* while (avl_iterator_next) */ + avl_iterator_destroy (iter); + + for (i = 0; i < keys_num; i++) + { + if (avl_remove (cache_tree, keys[i], (void *) &key, + (void *) &value) != 0) + { + WARNING ("network plugin: cache_flush: avl_remove" + " (%s) failed.", keys[i]); + continue; + } + + sfree (key); + sfree (value); + } + + sfree (keys); + + DEBUG ("network plugin: cache_flush: Removed %i %s", + keys_num, (keys_num == 1) ? "entry" : "entries"); + cache_flush_last = curtime; + return (0); +} /* int cache_flush */ + static int cache_check (const char *type, const value_list_t *vl) { char key[1024]; @@ -217,7 +277,8 @@ static int cache_check (const char *type, const value_list_t *vl) } } - /* TODO: Flush cache */ + if ((time (NULL) - cache_flush_last) > cache_flush_interval) + cache_flush (); pthread_mutex_unlock (&cache_lock); @@ -1195,12 +1256,19 @@ static int network_config (const char *key, const char *val) else network_config_forward = 0; } + else if (strcasecmp ("CacheFlush", key) == 0) + { + int tmp = atoi (val); + if (tmp > 0) + cache_flush_interval = tmp; + else return (1); + } else { return (-1); } return (0); -} +} /* int network_config */ static int network_shutdown (void) { @@ -1251,6 +1319,7 @@ static int network_init (void) memset (send_buffer_type, '\0', sizeof (send_buffer_type)); cache_tree = avl_create ((int (*) (const void *, const void *)) strcmp); + cache_flush_last = time (NULL); /* setup socket(s) and so on */ if (sending_sockets != NULL) -- 2.30.2