Code

utils strbuf: Added 'min_size' to be considered when shrinking the buffer.
authorSebastian Harl <sh@tokkee.org>
Wed, 17 Sep 2014 09:10:13 +0000 (11:10 +0200)
committerSebastian Harl <sh@tokkee.org>
Wed, 17 Sep 2014 09:10:13 +0000 (11:10 +0200)
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
t/unit/utils/strbuf_test.c

index c310b443448a14be1eb96f8c7fdc4618707868c5..ecc05315ef897f9d84a415ccecb9b6f77e89e9bd 100644 (file)
@@ -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;
index e7cb9f5a6438cfb9ba1cc30ed90835ab5dbcaeb1..cb86a3e1ef3edd75ba03f26da11996c5532c5c49 100644 (file)
@@ -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 < <size> < %d)",