--- doc/librrd.pod | 18 ++++++++++++++++++ src/rrd.h | 4 ++++ src/rrd_utils.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 64 insertions(+), 11 deletions(-)
diff --git a/doc/librrd.pod b/doc/librrd.pod index 038746c..396e50c 100644 --- a/doc/librrd.pod +++ b/doc/librrd.pod @@ -81,6 +81,16 @@ end of the new C<dest>. Returns 1 on success, 0 on failure. if (!rrd_add_ptr(&arr, &arr_size, elem)) handle_failure(); +=item B<rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)> + +Like C<rrd_add_ptr>, except the destination is allocated in chunks of +C<chunk>. C<alloc> points to the number of entries allocated, whereas +C<dest_size> points to the number of valid pointers. If more pointers are +needed, C<chunk> pointers are allocated and C<alloc> is increased +accordingly. C<alloc> must be E<gt>= C<dest_size>. + +This method improves performance on hosts with expensive C<realloc()>. + =item B<rrd_add_strdup(char ***dest, size_t *dest_size, char *src)> Like C<rrd_add_ptr>, except adds a C<strdup> of the source string. @@ -91,6 +101,14 @@ Like C<rrd_add_ptr>, except adds a C<strdup> of the source string. if (!rrd_add_strdup(&arr, &arr_size, str)) handle_failure(); +=item B<rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)> + +Like C<rrd_add_strdup>, except the destination is allocated in chunks of +C<chunk>. C<alloc> points to the number of entries allocated, whereas +C<dest_size> points to the number of valid pointers. If more pointers are +needed, C<chunk> pointers are allocated and C<alloc> is increased +accordingly. C<alloc> must be E<gt>= C<dest_size>. + =item B<rrd_free_ptrs(void ***src, size_t *cnt)> Free an array of pointers allocated by C<rrd_add_ptr> or diff --git a/src/rrd.h b/src/rrd.h index ce7e749..6008794 100644 --- a/src/rrd.h +++ b/src/rrd.h @@ -333,8 +333,12 @@ int rrd_proc_start_end( long rrd_random(void); + int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, + size_t *alloc, size_t chunk); int rrd_add_ptr(void ***dest, size_t *dest_size, void *src); int rrd_add_strdup(char ***dest, size_t *dest_size, char *src); + int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, + size_t *alloc, size_t chunk); void rrd_free_ptrs(void ***src, size_t *cnt); int rrd_mkdir_p(const char *pathname, mode_t mode); diff --git a/src/rrd_utils.c b/src/rrd_utils.c index 3936cff..6853c66 100644 --- a/src/rrd_utils.c +++ b/src/rrd_utils.c @@ -50,29 +50,53 @@ long rrd_random(void) return random(); } -/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers, - * realloc as necessary. returns 1 on success, 0 on failure. +/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of + * pointers, realloc as necessary in multiples of "chunk". + * + * "alloc" is the number of pointers allocated + * "dest_size" is the number of valid pointers + * + * returns 1 on success, 0 on failure. */ -int rrd_add_ptr(void ***dest, size_t *dest_size, void *src) +int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, + size_t *alloc, size_t chunk) { void **temp; assert(dest != NULL); + assert(alloc != NULL); + assert(*alloc >= *dest_size); - temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest)); - if (!temp) - return 0; + if (*alloc == *dest_size) + { + temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest)); + if (!temp) + return 0; - *dest = temp; - temp[*dest_size] = src; + *dest = temp; + *alloc += chunk; + } + + (*dest)[*dest_size] = src; (*dest_size)++; return 1; } -/* like rrd_add_ptr, but calls strdup() on a string first. */ -int rrd_add_strdup(char ***dest, size_t *dest_size, char *src) +/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers, + * realloc as necessary. returns 1 on success, 0 on failure. + */ +int rrd_add_ptr(void ***dest, size_t *dest_size, void *src) +{ + size_t alloc = *dest_size; + + return rrd_add_ptr_chunk(dest, dest_size, src, &alloc, 1); +} + +/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */ +int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, + size_t *alloc, size_t chunk) { char *dup_src; int add_ok; @@ -84,13 +108,20 @@ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src) if (!dup_src) return 0; - add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src); + add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk); if (!add_ok) free(dup_src); return add_ok; } +int rrd_add_strdup(char ***dest, size_t *dest_size, char *src) +{ + size_t alloc = *dest_size; + + return rrd_add_strdup_chunk(dest, dest_size, src, &alloc, 1); +} + void rrd_free_ptrs(void ***src, size_t *cnt) { void **sp; -- 1.6.4 _______________________________________________ rrd-developers mailing list rrd-developers@lists.oetiker.ch https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers