summaryrefslogtreecommitdiffstats
path: root/lib/buffer.c
diff options
context:
space:
mode:
authorGergely Nagy <algernon@madhouse-project.org>2012-04-29 11:12:39 +0200
committerGergely Nagy <algernon@madhouse-project.org>2012-04-29 11:19:06 +0200
commit4fd758dcde350fda5e87573d9c7004a35b136741 (patch)
treed599260e49788d159135d37fbc6afea431bb2e3c /lib/buffer.c
parent7dc0d11639d5f9fd2c4d0e01ab12813a5898f596 (diff)
downloadlibumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.tar.gz
libumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.tar.xz
libumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.zip
Reduce the number of memory allocations
Make the string escape use an ul_buffer_t, to avoid unnecessary memory allocations. This greatly reduces the number of mallocs made, and thus results in a noticable increase in speed. Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
Diffstat (limited to 'lib/buffer.c')
-rw-r--r--lib/buffer.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/lib/buffer.c b/lib/buffer.c
index 3d92224..ef448bf 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -54,11 +54,20 @@ static const unsigned char json_exceptions[] =
0xff, '\0'
};
+static __thread ul_buffer_t escape_buffer;
+
+static void ul_buffer_finish (void) __attribute__((destructor));
+
+static void
+ul_buffer_finish (void)
+{
+ free (escape_buffer.msg);
+}
+
static inline char *
-_ul_str_escape (const char *str, size_t *length)
+_ul_str_escape (const char *str, char *dest, size_t *length)
{
const unsigned char *p;
- char *dest;
char *q;
static unsigned char exmap[256];
static int exmap_inited;
@@ -67,7 +76,7 @@ _ul_str_escape (const char *str, size_t *length)
return NULL;
p = (unsigned char *)str;
- q = dest = malloc (strlen (str) * 6 + 1);
+ q = dest;
if (!exmap_inited)
{
@@ -171,35 +180,44 @@ ul_buffer_append (ul_buffer_t *buffer, const char *key, const char *value)
{
char *k, *v;
size_t lk, lv;
+ size_t orig_len = buffer->len;
- k = _ul_str_escape (key, &lk);
+ /* Append the key to the buffer */
+ escape_buffer.len = 0;
+ _ul_buffer_ensure_size (&escape_buffer, strlen (key) * 6 + 1);
+ k = _ul_str_escape (key, escape_buffer.msg, &lk);
if (!k)
return NULL;
- v = _ul_str_escape (value, &lv);
+
+ buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + 4);
+ if (!buffer)
+ return NULL;
+
+ memcpy (buffer->msg + buffer->len, "\"", 1);
+ memcpy (buffer->msg + buffer->len + 1, k, lk);
+ memcpy (buffer->msg + buffer->len + 1 + lk, "\":\"", 3);
+
+ /* Append the value to the buffer */
+ escape_buffer.len = 0;
+ _ul_buffer_ensure_size (&escape_buffer, strlen (value) * 6 + 1);
+ v = _ul_str_escape (value, escape_buffer.msg, &lv);
if (!v)
{
- free (k);
+ buffer->len = orig_len;
return NULL;
}
buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + lv + 6);
if (!buffer)
{
- free (k);
- free (v);
+ buffer->len = orig_len;
return NULL;
}
- memcpy (buffer->msg + buffer->len, "\"", 1);
- memcpy (buffer->msg + buffer->len + 1, k, lk);
- memcpy (buffer->msg + buffer->len + 1 + lk, "\":\"", 3);
memcpy (buffer->msg + buffer->len + 1 + lk + 3, v, lv);
memcpy (buffer->msg + buffer->len + 1 + lk + 3 + lv, "\",", 2);
buffer->len += lk + lv + 6;
- free (k);
- free (v);
-
return buffer;
}