From 3cd97771183ee38e5fc8c3b2268cffce3c2cb27c Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 17 Sep 2014 11:10:13 +0200 Subject: [PATCH] utils strbuf: Added 'min_size' to be considered when shrinking the buffer. It's set to the initial size of the buffer (or 64). The idea is that the initial size should provide an estimate of a reasonable size and shrinking the buffer below that size causes unecessary churn. For example, this is important for the frontend's command handlers which usually need a large buffer size but initial writes to the buffer may be small. --- src/utils/strbuf.c | 9 ++++++++- t/unit/utils/strbuf_test.c | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/utils/strbuf.c b/src/utils/strbuf.c index c310b44..ecc0531 100644 --- a/src/utils/strbuf.c +++ b/src/utils/strbuf.c @@ -39,7 +39,8 @@ /* free memory if most of the buffer is unused */ #define CHECK_SHRINK(buf) \ do { \ - if ((buf)->pos < (buf)->size / 3) \ + if (((buf)->pos < (buf)->size / 3) \ + && (2 * (buf)->pos > (buf)->min_size)) \ /* don't free all memory to avoid churn */ \ strbuf_resize((buf), 2 * (buf)->pos); \ } while (0) @@ -52,6 +53,9 @@ struct sdb_strbuf { char *string; size_t size; size_t pos; + + /* min size to shrink the buffer to */ + size_t min_size; }; /* @@ -100,7 +104,10 @@ sdb_strbuf_create(size_t size) } buf->string[0] = '\0'; + buf->min_size = size; } + else + buf->min_size = 64; buf->size = size; buf->pos = 0; diff --git a/t/unit/utils/strbuf_test.c b/t/unit/utils/strbuf_test.c index e7cb9f5..cb86a3e 100644 --- a/t/unit/utils/strbuf_test.c +++ b/t/unit/utils/strbuf_test.c @@ -233,6 +233,9 @@ START_TEST(test_sprintf) size_t i; + sdb_strbuf_destroy(buf); + buf = sdb_strbuf_create(1); /* -> min_size = 1 */ + for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) { n = sdb_strbuf_sprintf(buf, "%s", golden_data[i]); fail_unless((size_t)n == strlen(golden_data[i]), @@ -251,7 +254,9 @@ START_TEST(test_sprintf) "got: %s; expected: %s", test, golden_data[i]); check = sdb_strbuf_cap(buf); - if (n) /* 3 times the current len is the threshold for shrinking */ + /* 3 times the current len is the threshold for shrinking, + * but it's capped to the initial size (or 64) */ + if (n) fail_unless(((size_t)n < check) && (check < (size_t)n * 3), "sdb_strbuf_sprintf() did not resize the buffer " "correctly (got size %zu; expected %zi < < %d)", -- 2.30.2