From: Florian Forster Date: Sun, 7 Oct 2012 07:42:28 +0000 (+0200) Subject: rc/utils_cache.c: Allocate most of the memory required by uc_get_names() at once. X-Git-Tag: collectd-5.2.0~40 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=b9390e53e68f70cac2a6b5122214a86bfb51ae65;p=collectd.git rc/utils_cache.c: Allocate most of the memory required by uc_get_names() at once. strdup() will still require additional memory, but no more memory movement like required when doing realloc() a lot. This fixes Github issue #148. --- diff --git a/src/utils_cache.c b/src/utils_cache.c index 82567f33..539545ac 100644 --- a/src/utils_cache.c +++ b/src/utils_cache.c @@ -593,47 +593,47 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) pthread_mutex_lock (&cache_lock); + size_arrays = (size_t) c_avl_size (cache_tree); + if (size_arrays < 1) + { + /* Handle the "no values" case here, to avoid the error message when + * calloc() returns NULL. */ + pthread_mutex_lock (&cache_lock); + return (0); + } + + names = calloc (size_arrays, sizeof (*names)); + times = calloc (size_arrays, sizeof (*times)); + if ((names == NULL) || (times == NULL)) + { + ERROR ("uc_get_names: calloc failed."); + sfree (names); + sfree (times); + pthread_mutex_lock (&cache_lock); + return (ENOMEM); + } + iter = c_avl_get_iterator (cache_tree); while (c_avl_iterator_next (iter, (void *) &key, (void *) &value) == 0) { - char **temp; - /* remove missing values when list values */ if (value->state == STATE_MISSING) continue; + /* c_avl_size does not return a number smaller than the number of elements + * returned by c_avl_iterator_next. */ + assert (number < size_arrays); + if (ret_times != NULL) - { - cdtime_t *tmp_times; - - if(number <= size_arrays) { - tmp_times = (cdtime_t *) realloc (times, sizeof (cdtime_t) * (size_arrays + LISTVAL_INCREASE)); - if (tmp_times == NULL) - { - status = -1; - break; - } - times = tmp_times; - } times[number] = value->last_time; - } - if(number <= size_arrays) { - temp = (char **) realloc (names, sizeof (char *) * (size_arrays + LISTVAL_INCREASE)); - if (temp == NULL) - { - status = -1; - break; - } - names = temp; - size_arrays += LISTVAL_INCREASE; - } names[number] = strdup (key); if (names[number] == NULL) { status = -1; break; } + number++; } /* while (c_avl_iterator_next) */