Better resize rotine, linear instead of double.
authorbarbieri <barbieri>
Sat, 27 Feb 2010 16:41:24 +0000 (16:41 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 27 Feb 2010 16:41:24 +0000 (16:41 +0000)
Increment in steps linearly instead of doubling them, otherwise it
will get to maximum limit of 4096 too soon.

Also replace the loop with simple math.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eina@46585 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/eina_strbuf.c
src/tests/eina_test_strbuf.c

index a28b9e9..ee5bd49 100644 (file)
@@ -717,50 +717,34 @@ _eina_strbuf_grow(Eina_Strbuf *buf, size_t size)
 static inline Eina_Bool
 _eina_strbuf_resize(Eina_Strbuf *buf, size_t size)
 {
+   size_t new_size, new_step, delta;
    char *buffer;
-   size_t new_size;
-   size_t new_step;
 
    size += 1; // Add extra space for '\0'
 
-   new_size = buf->size;
-   new_step = buf->step;
-
-   /*
-    * first we have to determine the new buffer size
-    */
    if (size == buf->size)
      /* nothing to do */
      return EINA_TRUE;
    else if (size > buf->size)
-     {
-       /* enlarge the buffer */
-       while (size > new_size)
-         {
-            new_size += new_step;
-            if (new_step < EINA_STRBUF_MAX_STEP)
-              new_step *= 2;
-            if (new_step > EINA_STRBUF_MAX_STEP)
-              new_step = EINA_STRBUF_MAX_STEP;
-         }
-     }
+     delta = size - buf->size;
+   else
+     delta = buf->size - size;
+
+   /* check if should keep the same step (just used while growing) */
+   if ((delta <= buf->step) && (size > buf->size))
+     new_step = buf->step;
    else
      {
-       /* shrink the buffer */
-       if (new_step > EINA_STRBUF_INIT_STEP)
-         new_step /= 2;
-       while (new_size - new_step > size)
-         {
-            new_size -= new_step;
-            if (new_step > EINA_STRBUF_INIT_STEP)
-              new_step /= 2;
-            if (new_step < EINA_STRBUF_INIT_STEP)
-              new_step = EINA_STRBUF_INIT_STEP;
-         }
+       new_step = (((delta / EINA_STRBUF_INIT_STEP) + 1)
+                   * EINA_STRBUF_INIT_STEP);
+
+       if (new_step > EINA_STRBUF_MAX_STEP)
+         new_step = EINA_STRBUF_MAX_STEP;
      }
 
+   new_size = (((size / new_step) + 1) * new_step);
+
    /* reallocate the buffer to the new size */
-   eina_error_set(0);
    buffer = realloc(buf->buf, new_size);
    if (EINA_UNLIKELY(!buffer))
      {
@@ -771,6 +755,7 @@ _eina_strbuf_resize(Eina_Strbuf *buf, size_t size)
    buf->buf = buffer;
    buf->size = new_size;
    buf->step = new_step;
+   eina_error_set(0);
    return EINA_TRUE;
 }
 
index 9c8ae59..a2ad749 100644 (file)
@@ -252,6 +252,74 @@ START_TEST(strbuf_replace)
 }
 END_TEST
 
+START_TEST(strbuf_realloc)
+{
+   Eina_Strbuf *buf;
+   char pattern[1024 * 16];
+   unsigned int i;
+   size_t sz;
+
+   for (i = 0; i < sizeof(pattern) - 1; i++)
+     pattern[i] = 'a' + (i % 26);
+   pattern[i] = '\0';
+
+   eina_init();
+
+   buf = eina_strbuf_new();
+   fail_if(!buf);
+
+   sz = 0;
+
+   eina_strbuf_append_length(buf, pattern, 1);
+   fail_if(eina_strbuf_length_get(buf) != sz + 1);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 1));
+   sz += 1;
+
+   eina_strbuf_append_length(buf, pattern, 32);
+   fail_if(eina_strbuf_length_get(buf) != sz + 32);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 32));
+   sz += 32;
+
+   eina_strbuf_append_length(buf, pattern, 64);
+   fail_if(eina_strbuf_length_get(buf) != sz + 64);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 64));
+   sz += 64;
+
+   eina_strbuf_append_length(buf, pattern, 128);
+   fail_if(eina_strbuf_length_get(buf) != sz + 128);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 128));
+   sz += 128;
+
+   eina_strbuf_append_length(buf, pattern, 4096);
+   fail_if(eina_strbuf_length_get(buf) != sz + 4096);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, 4096));
+   sz += 4096;
+
+   eina_strbuf_append_length(buf, pattern, sizeof(pattern) - 1);
+   fail_if(eina_strbuf_length_get(buf) != sz + sizeof(pattern) - 1);
+   fail_if(memcmp(eina_strbuf_string_get(buf) + sz, pattern, sizeof(pattern) - 1));
+   sz += sizeof(pattern) - 1;
+
+
+   eina_strbuf_remove(buf, 1024, 1024 + 1234);
+   fail_if(eina_strbuf_length_get(buf) != sz - 1234);
+   sz -= 1234;
+
+   eina_strbuf_remove(buf, 0, 0 + 8192);
+   fail_if(eina_strbuf_length_get(buf) != sz - 8192);
+   sz -= 8192;
+
+   eina_strbuf_remove(buf, 0, 0 + 32);
+   fail_if(eina_strbuf_length_get(buf) != sz - 32);
+   sz -= 32;
+
+
+   eina_strbuf_free(buf);
+
+   eina_shutdown();
+}
+END_TEST
+
 START_TEST(strbuf_append_realloc)
 {
    Eina_Strbuf *buf;
@@ -330,6 +398,7 @@ eina_test_strbuf(TCase *tc)
    tcase_add_test(tc, strbuf_append);
    tcase_add_test(tc, strbuf_insert);
    tcase_add_test(tc, strbuf_replace);
+   tcase_add_test(tc, strbuf_realloc);
    tcase_add_test(tc, strbuf_append_realloc);
    tcase_add_test(tc, strbuf_prepend_realloc);
 }