summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2018-11-23 18:46:39 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2018-11-25 19:52:08 -0500
commit75bd40aa5d9fd4633afcd1a0afc589c07f56dec9 (patch)
tree87304323565099dffe0a0eecb408098773220936 /src/buffer.c
parentcced512116b33589f34bd1b3e7fedefa73472a98 (diff)
downloadlighttpd-git-75bd40aa5d9fd4633afcd1a0afc589c07f56dec9.tar.gz
[core] perf: buffer optimizations
buffer_string_prepare_copy() no longer writes '\0' into b->ptr buffer_realloc() always allocates extra +1 for '\0'
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c86
1 files changed, 29 insertions, 57 deletions
diff --git a/src/buffer.c b/src/buffer.c
index e7a71f62..37f11f1f 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -73,54 +73,35 @@ void buffer_move(buffer *b, buffer *src) {
tmp = *src; *src = *b; *b = tmp;
}
-#define BUFFER_PIECE_SIZE 64uL /*(must be power-of-2)*/
-static size_t buffer_align_size(size_t size) {
- size_t aligned = (size + BUFFER_PIECE_SIZE-1) & ~(BUFFER_PIECE_SIZE-1);
- force_assert(aligned >= size);
- return aligned;
-}
-
-/* make sure buffer is at least "size" big. discard old data */
-static void buffer_alloc(buffer *b, size_t size) {
- force_assert(NULL != b);
- if (0 == size) size = 1;
-
- if (size <= b->size) return;
-
- if (NULL != b->ptr) free(b->ptr);
+/* make sure buffer is at least "size" big + 1 for '\0'. keep old data */
+__attribute_cold__
+static void buffer_realloc(buffer *b, size_t len) {
+ #define BUFFER_PIECE_SIZE 64uL /*(must be power-of-2)*/
+ const size_t sz = (len + 1 + BUFFER_PIECE_SIZE-1) & ~(BUFFER_PIECE_SIZE-1);
+ force_assert(sz > len);
- b->used = 0;
- b->size = buffer_align_size(size);
- b->ptr = malloc(b->size);
+ b->size = sz;
+ b->ptr = realloc(b->ptr, sz);
- force_assert(NULL != b->ptr);
+ force_assert(NULL != b->ptr);
}
-/* make sure buffer is at least "size" big. keep old data */
-static void buffer_realloc(buffer *b, size_t size) {
- force_assert(NULL != b);
- if (0 == size) size = 1;
-
- if (size <= b->size) return;
-
- b->size = buffer_align_size(size);
- b->ptr = realloc(b->ptr, b->size);
-
- force_assert(NULL != b->ptr);
+__attribute_cold__
+static void buffer_alloc_replace(buffer *b, size_t size) {
+ /*(discard old data so realloc() does not copy)*/
+ if (NULL != b->ptr) {
+ free(b->ptr);
+ b->ptr = NULL;
+ }
+ buffer_realloc(b, size);
}
-
char* buffer_string_prepare_copy(buffer *b, size_t size) {
force_assert(NULL != b);
- if (size >= b->size) {
- force_assert(size + 1 > size);
- buffer_alloc(b, size + 1);
- }
-
- b->used = 1;
- b->ptr[0] = '\0';
+ if (size >= b->size) buffer_alloc_replace(b, size);
+ b->used = 0;
return b->ptr;
}
@@ -148,10 +129,7 @@ char* buffer_string_prepare_append(buffer *b, size_t size) {
void buffer_string_set_length(buffer *b, size_t len) {
force_assert(NULL != b);
- if (len >= b->size) {
- force_assert(len + 1 > len);
- buffer_realloc(b, len + 1);
- }
+ if (len >= b->size) buffer_realloc(b, len);
b->used = len + 1;
b->ptr[len] = '\0';
@@ -166,10 +144,10 @@ void buffer_commit(buffer *b, size_t size)
if (size > 0) {
/* check for overflow: unsigned overflow is defined to wrap around */
- force_assert(b->used + size > b->used);
-
- force_assert(b->used + size <= b->size);
- b->used += size;
+ size_t sz = b->used + size;
+ force_assert(sz > b->used);
+ force_assert(sz <= b->size);
+ b->used = sz;
}
b->ptr[b->used - 1] = '\0';
@@ -193,7 +171,6 @@ void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
void buffer_copy_buffer(buffer *b, const buffer *src) {
if (NULL == src || 0 == src->used) {
buffer_string_prepare_copy(b, 0);
- b->used = 0; /* keep special empty state for now */
} else {
buffer_copy_string_len(b, src->ptr, buffer_string_length(src));
}
@@ -221,10 +198,10 @@ void buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
force_assert(NULL != s || s_len == 0);
target_buf = buffer_string_prepare_append(b, s_len);
+ if (0 == b->used) ++b->used; /*(must include '\0' for append below)*/
- if (0 == s_len) return; /* nothing to append *//*(s might be NULL)*/
-
- memcpy(target_buf, s, s_len);
+ /*(s might be NULL if 0 == s_len)*/
+ if (s_len) memcpy(target_buf, s, s_len);
target_buf[s_len] = '\0';
b->used += s_len;
}
@@ -297,14 +274,9 @@ void buffer_append_strftime(buffer *b, const char *format, const struct tm *tm)
size_t r;
char* buf;
force_assert(NULL != b);
+ force_assert(NULL != format);
force_assert(NULL != tm);
- if (NULL == format || '\0' == format[0]) {
- /* empty format */
- buffer_string_prepare_append(b, 0);
- return;
- }
-
buf = buffer_string_prepare_append(b, 255);
r = strftime(buf, buffer_string_space(b), format, tm);
@@ -836,7 +808,7 @@ void buffer_path_simplify(buffer *dest, buffer *src)
force_assert(NULL != dest && NULL != src);
if (buffer_string_is_empty(src)) {
- buffer_string_prepare_copy(dest, 0);
+ buffer_copy_string_len(dest, CONST_STR_LEN(""));
return;
}