forked from enlightenment/efl
TES
Conflicts: src/lib/eina/eina_list.c src/lib/eina/eina_types.h
This commit is contained in:
parent
b71a17b9db
commit
d0f3357f77
|
@ -1094,6 +1094,85 @@ eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func)
|
|||
return list;
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
eina_list_shuffle(Eina_List *list, Eina_Random_Cb func)
|
||||
{
|
||||
unsigned int n, i, j;
|
||||
Eina_List_Accounting *accounting;
|
||||
Eina_List *shuffled_list, *shuffled_last, *li;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
EINA_MAGIC_CHECK_LIST(list, NULL);
|
||||
|
||||
accounting = list->accounting;
|
||||
n = accounting->count;
|
||||
shuffled_list = shuffled_last = NULL;
|
||||
|
||||
if (n == 1)
|
||||
return list;
|
||||
|
||||
while (n > 1)
|
||||
{
|
||||
if (func)
|
||||
i = func(0, (n - 1));
|
||||
else
|
||||
i = (int) ((float)n*rand()/(RAND_MAX+1.0));
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
li = list;
|
||||
list = list->next;
|
||||
}
|
||||
else if (i == (n - 1) || i == n)
|
||||
{
|
||||
li = accounting->last;
|
||||
accounting->last = li->prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i > (n / 2))
|
||||
for (j = n - 1,
|
||||
li = accounting->last;
|
||||
j!=i;
|
||||
li = li->prev, j--);
|
||||
else
|
||||
for (j = 0,
|
||||
li = list;
|
||||
j!=i;
|
||||
li = li->next, j++);
|
||||
|
||||
li->prev->next = li->next;
|
||||
li->next->prev = li->prev;
|
||||
}
|
||||
|
||||
n--;
|
||||
|
||||
if (shuffled_list == NULL)
|
||||
{
|
||||
li->prev = NULL;
|
||||
shuffled_list = li;
|
||||
shuffled_last = li;
|
||||
}
|
||||
else
|
||||
{
|
||||
shuffled_last->next = li;
|
||||
li->prev = shuffled_last;
|
||||
shuffled_last = li;
|
||||
}
|
||||
}
|
||||
|
||||
list->next = NULL;
|
||||
list->prev = shuffled_last;
|
||||
shuffled_last->next = list;
|
||||
|
||||
accounting->last = list;
|
||||
shuffled_list->accounting = accounting;
|
||||
|
||||
return shuffled_list;
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
eina_list_merge(Eina_List *left, Eina_List *right)
|
||||
{
|
||||
|
|
|
@ -333,6 +333,21 @@ typedef int (*Eina_Compare_Cb)(const void *data1, const void *data2);
|
|||
*/
|
||||
#define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function)
|
||||
|
||||
/**
|
||||
* @typedef Eina_Random_Cb
|
||||
* Function used in shuffling functions. An integer betwen min and max
|
||||
* inclusive must be returned.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
typedef int (*Eina_Random_Cb)(const int min, const int max);
|
||||
|
||||
/**
|
||||
* @def EINA_RANDOM_CB
|
||||
* Macro to cast to Eina_Random_Cb.
|
||||
*/
|
||||
#define EINA_RANDOM_CB(function) ((Eina_Random_Cb)function)
|
||||
|
||||
/**
|
||||
* @typedef Eina_Each_Cb
|
||||
* A callback type used when iterating over a container.
|
||||
|
|
|
@ -375,6 +375,62 @@ START_TEST(eina_test_list_split)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static int uicmp(const void *d1, const void *d2)
|
||||
{
|
||||
const unsigned int *a = d1;
|
||||
const unsigned int *b = d2;
|
||||
|
||||
if(*a == *b) return 0;
|
||||
if(*a > *b) return 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define SHUFFLE_SZ 100
|
||||
#define SHUFFLE_N 100000
|
||||
START_TEST(eina_test_shuffle)
|
||||
{
|
||||
double d;
|
||||
unsigned int *p;
|
||||
unsigned int i, j;
|
||||
unsigned int n[SHUFFLE_SZ];
|
||||
unsigned int rand_count[SHUFFLE_SZ];
|
||||
Eina_List *list = NULL;
|
||||
Eina_List *item = NULL;
|
||||
|
||||
eina_init();
|
||||
|
||||
for(i = 0; i < SHUFFLE_SZ; i++)
|
||||
{
|
||||
n[i] = i;
|
||||
rand_count[i] = 0;
|
||||
list = eina_list_append(list, &n[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < SHUFFLE_N; i++)
|
||||
{
|
||||
list = eina_list_shuffle(list, NULL);
|
||||
p = eina_list_nth(list, SHUFFLE_SZ/2);
|
||||
rand_count[*p]++;
|
||||
|
||||
j = 0;
|
||||
list = eina_list_sort(list, 0, (Eina_Compare_Cb)&uicmp);
|
||||
EINA_LIST_FOREACH(list, item, p)
|
||||
fail_if(*p != j++);
|
||||
fail_if(j != SHUFFLE_SZ);
|
||||
}
|
||||
|
||||
d = SHUFFLE_SZ/(float)(SHUFFLE_N);
|
||||
for(i = 0; i < SHUFFLE_SZ; i++)
|
||||
{
|
||||
fail_if(rand_count[i]*d > 1.20f);
|
||||
fail_if(rand_count[i]*d < 0.80f);
|
||||
}
|
||||
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_list(TCase *tc)
|
||||
{
|
||||
|
@ -382,4 +438,5 @@ eina_test_list(TCase *tc)
|
|||
tcase_add_test(tc, eina_test_merge);
|
||||
tcase_add_test(tc, eina_test_sorted_insert);
|
||||
tcase_add_test(tc, eina_test_list_split);
|
||||
tcase_add_test(tc, eina_test_shuffle);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue