roken: Make strpool more efficient

Grow the buffer more than absolutely needed, but not too fast.
This commit is contained in:
Nicolas Williams
2021-01-14 18:21:09 -06:00
parent 333af2051c
commit 5cefb340ac
2 changed files with 26 additions and 19 deletions

View File

@@ -20,7 +20,7 @@ if HAVE_DBHEADER
AM_CPPFLAGS += -I$(DBHEADER)
endif
noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rkvis rkbase32 rkbase64
noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rkvis rkbase32 rkbase64 rtbl
CHECK_LOCAL = snprintf-test resolve-test rkpty make-roken
@@ -67,6 +67,9 @@ rkbase32_CPPFLAGS = -DTEST
rkbase64_SOURCES = base64.c
rkbase64_CPPFLAGS = -DTEST
rtbl_SOURCES = rtbl.c
rtbl_CPPFLAGS = -DTEST
test_detach_SOURCES = test-detach.c
rkpty_LDADD = $(LIB_openpty) $(LDADD)

View File

@@ -39,7 +39,8 @@
struct rk_strpool {
char *str;
size_t len;
size_t len; /* strlen() of str */
size_t sz; /* Allocated size */
};
/*
@@ -64,29 +65,32 @@ ROKEN_LIB_FUNCTION struct rk_strpool * ROKEN_LIB_CALL
rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...)
{
va_list ap;
char *str, *str2;
char *str;
int len;
if (p == NULL) {
p = malloc(sizeof(*p));
if (p == NULL)
return NULL;
p->str = NULL;
p->len = 0;
}
va_start(ap, fmt);
len = vasprintf(&str, fmt, ap);
va_end(ap);
if (str == NULL) {
rk_strpoolfree(p);
return NULL;
if (str == NULL)
return rk_strpoolfree(p), NULL;
if (p == NULL) {
if ((p = malloc(sizeof(*p))) == NULL)
return free(str), NULL;
p->str = str;
p->len = p->sz = len;
return p;
} /* else grow the buffer and append `str', but don't grow too fast */
if (len + p->len + 1 > p->sz) {
size_t sz = p->len + len + 9 + (p->sz >> 2);
char *str2;
if ((str2 = realloc(p->str, sz)) == NULL)
return rk_strpoolfree(p), NULL;
p->str = str2;
p->sz = sz;
}
str2 = realloc(p->str, len + p->len + 1);
if (str2 == NULL) {
rk_strpoolfree(p);
return NULL;
}
p->str = str2;
memcpy(p->str + p->len, str, len + 1);
p->len += len;
free(str);