Mercurial > dovecot > core-2.2
changeset 22637:da955f909fdd
lib: *_strsplit() - implement more efficient version for a single separator char
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 04 Nov 2017 01:40:24 +0200 |
parents | 96e51a11c0aa |
children | 7d5634889da8 |
files | src/lib/strfuncs.c |
diffstat | 1 files changed, 46 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/strfuncs.c Sat Nov 04 01:39:38 2017 +0200 +++ b/src/lib/strfuncs.c Sat Nov 04 01:40:24 2017 +0200 @@ -492,14 +492,12 @@ } static char ** -split_str(pool_t pool, const char *data, const char *separators, int spaces) +split_str_slow(pool_t pool, const char *data, const char *separators, bool spaces) { char **array; char *str; unsigned int count, alloc_count, new_alloc_count; - i_assert(*separators != '\0'); - if (spaces) { /* skip leading separators */ while (*data != '\0' && strchr(separators, *data) != NULL) @@ -549,6 +547,51 @@ return array; } +static char ** +split_str_fast(pool_t pool, const char *data, char sep) +{ + char **array, *str; + unsigned int count, alloc_count, new_alloc_count; + + if (*data == '\0') + return p_new(pool, char *, 1); + + str = p_strdup(pool, data); + + alloc_count = 32; + array = p_new(pool, char *, alloc_count); + + array[0] = str; count = 1; + while ((str = strchr(str, sep)) != NULL) { + /* separator found */ + if (count+1 >= alloc_count) { + new_alloc_count = nearest_power(alloc_count+1); + array = p_realloc(pool, array, + sizeof(char *) * alloc_count, + sizeof(char *) * + new_alloc_count); + alloc_count = new_alloc_count; + } + *str++ = '\0'; + array[count++] = str; + } + i_assert(count < alloc_count); + i_assert(array[count] == NULL); + + return array; +} + +static char ** +split_str(pool_t pool, const char *data, const char *separators, bool spaces) +{ + i_assert(*separators != '\0'); + + if (separators[1] == '\0' && !spaces) + return split_str_fast(pool, data, separators[0]); + else + return split_str_slow(pool, data, separators, spaces); +} + const char **t_strsplit(const char *data, const char *separators) { return (const char **)split_str(unsafe_data_stack_pool, data,