[vlc-devel] [RFC 3/3] vlc_arrays: append items in amortized O(1)
Steve Lhomme
robux4 at ycbcr.xyz
Fri Jul 20 13:49:21 CEST 2018
I think there should be a commit before this one with adding the test
(with the preexisting API) and then adding more tests with the new API
if there's any.
On 19/07/2018 17:57, Romain Vimont wrote:
> +
> /*****************************************************************************
> * I18n stuff
> *****************************************************************************/
> @@ -1180,6 +1184,7 @@ VLC_API const char * VLC_Compiler( void ) VLC_USED;
> /*****************************************************************************
> * Additional vlc stuff
> *****************************************************************************/
> +#include "vlc_arrays.h"
> #include "vlc_messages.h"
> #include "vlc_objects.h"
> #include "vlc_variables.h"
> diff --git a/src/test/arrays.c b/src/test/arrays.c
> index 82277bbbc12..b7f5b829bd4 100644
> --- a/src/test/arrays.c
> +++ b/src/test/arrays.c
> @@ -1,5 +1,5 @@
> /*****************************************************************************
> - * arrays.h : Test for ARRAY_* macros
> + * arrays.h : Test for VLC arrays
> *****************************************************************************
> * Copyright (C) 2018 VLC authors and VideoLAN
> *
> @@ -158,10 +158,176 @@ static void test_array_bsearch(void)
> ARRAY_RESET(array);
> }
>
> +static void test_vlc_array_insert_remove(void)
> +{
> + vlc_array_t array;
> + vlc_array_init(&array);
> +
> + char data[32];
> +
> + vlc_array_append(&array, &data[0]);
> + assert(vlc_array_count(&array) == 1);
> + assert(vlc_array_get(&array, 0) == &data[0]);
> +
> + vlc_array_remove(&array, 0);
> + assert(vlc_array_count(&array) == 0);
> +
> + vlc_array_append(&array, &data[1]);
> + vlc_array_append(&array, &data[2]);
> + vlc_array_append(&array, &data[3]);
> + vlc_array_remove(&array, 1);
> + assert(vlc_array_count(&array) == 2);
> + assert(vlc_array_get(&array, 0) == &data[1]);
> + assert(vlc_array_get(&array, 1) == &data[3]);
> +
> + vlc_array_insert(&array, &data[4], 1);
> + assert(vlc_array_count(&array) == 3);
> + assert(vlc_array_get(&array, 0) == &data[1]);
> + assert(vlc_array_get(&array, 1) == &data[4]);
> + assert(vlc_array_get(&array, 2) == &data[3]);
> +
> + vlc_array_clear(&array);
> +}
> +
> +static void test_vlc_array_find(void)
> +{
> + vlc_array_t array;
> + vlc_array_init(&array);
> +
> + char data[10];
> +
> + for (int i = 0; i < 10; ++i)
> + vlc_array_append(&array, &data[i]);
> +
> + ssize_t idx;
> +
> + idx = vlc_array_find(&array, &data[0]);
> + assert(idx == 0);
> +
> + idx = vlc_array_find(&array, &data[1]);
> + assert(idx == 1);
> +
> + idx = vlc_array_find(&array, &data[4]);
> + assert(idx == 4);
> +
> + idx = vlc_array_find(&array, &data[9]);
> + assert(idx == 9);
> +
> + idx = vlc_array_find(&array, "some other pointer");
> + assert(idx == -1);
> +
> + vlc_array_clear(&array);
> +}
> +
> +static void test_vlc_array_grow()
> +{
> + vlc_array_t array;
> + vlc_array_init(&array);
> +
> + char data;
> +
> + for (int i = 0; i < 50; ++i)
> + vlc_array_append(&array, &data); /* append */
> +
> + assert(vlc_array_count(&array) == 50);
> +
> + for (int i = 0; i < 25; ++i)
> + vlc_array_insert(&array, &data, 20); /* insert from the middle */
> +
> + assert(vlc_array_count(&array) == 75);
> +
> + for (int i = 0; i < 25; ++i)
> + vlc_array_insert(&array, &data, 0); /* prepend */
> +
> + assert(vlc_array_count(&array) == 100);
> +
> + for (int i = 0; i < 50; ++i)
> + vlc_array_remove(&array, 20); /* remove from the middle */
> +
> + assert(vlc_array_count(&array) == 50);
> +
> + for (int i = 0; i < 25; ++i)
> + vlc_array_remove(&array, 0); /* remove from the head */
> +
> + assert(vlc_array_count(&array) == 25);
> +
> + for (int i = 24; i >= 0; --i)
> + vlc_array_remove(&array, i); /* remove from the tail */
> +
> + assert(vlc_array_count(&array) == 0);
> +
> + vlc_array_clear(&array);
> +}
> +
> +static void test_vlc_array_exp_growth()
> +{
> + vlc_array_t array;
> + vlc_array_init(&array);
> +
> + char data;
> + size_t old_capacity = array.i_capacity;
> + int realloc_count = 0;
> + for (int i = 0; i < 10000; ++i)
> + {
> + vlc_array_append(&array, &data);
> + if (array.i_capacity != old_capacity)
> + {
> + realloc_count++;
> + old_capacity = array.i_capacity;
> + }
> + }
> +
> + /* Test specifically for an expected growth factor of 1.5. In practice, the
> + * result is even lower (19) due to the first alloc of size 10 */
> + assert(realloc_count <= 23); /* ln(10000) / ln(1.5) ~= 23 */
> +
> + realloc_count = 0;
> + for (int i = 9999; i >= 0; --i)
> + {
> + vlc_array_remove(&array, i);
> + if (array.i_capacity != old_capacity)
> + {
> + realloc_count++;
> + old_capacity = array.i_capacity;
> + }
> + }
> +
> + /* Same expectation for removals */
> + assert(realloc_count <= 23);
> +
> + vlc_array_clear(&array);
> +}
> +
> +static void test_vlc_array_reserve()
> +{
> + vlc_array_t array;
> + vlc_array_init(&array);
> +
> + vlc_array_reserve(&array, 800);
> + assert(array.i_capacity >= 800);
> +
> + size_t initial_capacity = array.i_capacity;
> +
> + char data;
> + for (int i = 0; i < 800; ++i)
> + {
> + vlc_array_append(&array, &data);
> + assert(array.i_capacity == initial_capacity); /* no realloc */
> + }
> +
> + vlc_array_clear(&array);
> +}
> +
> int main(void)
> {
> test_array_insert_remove();
> test_array_foreach();
> test_array_find();
> test_array_bsearch();
> +
> + test_vlc_array_insert_remove();
> + test_vlc_array_find();
> + test_vlc_array_grow();
> + test_vlc_array_reserve();
> + test_vlc_array_exp_growth();
> }
> --
> 2.18.0
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list