Better resize rotine, linear instead of double.

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.



SVN revision: 46585
This commit is contained in:
Gustavo Sverzut Barbieri 2010-02-27 16:41:24 +00:00
parent 4d9ed8cb79
commit 54b0b06c1e
2 changed files with 85 additions and 31 deletions

View 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;
}

View 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);
}