return prev;
}
+static void
+_eina_inlist_sorted_state_compact(Eina_Inlist_Sorted_State *state)
+{
+ unsigned short i, j;
+
+ /* compress the jump table */
+ state->jump_div *= 2;
+ state->jump_limit /= 2;
+
+ for (i = 2, j = 1;
+ i < EINA_INLIST_JUMP_SIZE;
+ i += 2, j++)
+ state->jump_table[j] = state->jump_table[i];
+}
+
/**
* @endcond
*/
return i;
}
-EAPI void
+EAPI int
eina_inlist_sorted_state_init(Eina_Inlist_Sorted_State *state, Eina_Inlist *list)
{
Eina_Inlist *ct = NULL;
{
if (state->jump_limit == EINA_INLIST_JUMP_SIZE)
{
- unsigned short i, j;
-
- /* compress the jump table */
- state->jump_div *= 2;
- state->jump_limit /= 2;
-
- for (i = 2, j = 1;
- i < EINA_INLIST_JUMP_SIZE;
- i += 2, j++)
- state->jump_table[j] = state->jump_table[i];
+ _eina_inlist_sorted_state_compact(state);
}
state->jump_table[state->jump_limit] = ct;
jump_count = 0;
}
}
+
+ state->inserted = count;
+ return count;
}
EAPI Eina_Inlist_Sorted_State *
{
Eina_Inlist *last;
int jump_count;
+ int start;
state->inserted++;
state->jump_table[index] = state->jump_table[index]->prev;
}
- last = state->jump_table[state->jump_limit - 1];
- for (jump_count = 0; last != NULL; last = last->next)
- jump_count++;
+ start = state->jump_limit - 3;
+ if (start < 0)
+ start = 0;
- if (jump_count == state->jump_div + 1)
+ last = state->jump_table[start];
+ start++;
+
+ /* Correctly rebuild end of list */
+ for (jump_count = 0; last->next != NULL; last = last->next, jump_count++)
{
- if (state->jump_limit == EINA_INLIST_JUMP_SIZE)
+ if (jump_count == state->jump_div)
{
- unsigned short i, j;
-
- /* compress the jump table */
- state->jump_div *= 2;
- state->jump_limit /= 2;
+ if (state->jump_limit == start)
+ {
+ if (state->jump_limit == EINA_INLIST_JUMP_SIZE)
+ {
+ _eina_inlist_sorted_state_compact(state);
+ start = state->jump_limit - 1;
+ continue ;
+ }
+ else
+ {
+ state->jump_limit++;
+ }
+ }
- for (i = 2, j = 1;
- i < EINA_INLIST_JUMP_SIZE;
- i += 2, j++)
- state->jump_table[j] = state->jump_table[i];
+ state->jump_table[start++] = last;
+ jump_count = 0;
}
- state->jump_table[state->jump_limit] = state->jump_table[0]->last;
- state->jump_limit++;
}
}
int cmp = 0;
int inf, sup;
int cur = 0;
- int count = 0;
+ int count;
if (!list) return eina_inlist_append(NULL, item);
state.jump_div = 1;
state.jump_limit = 0;
- eina_inlist_sorted_state_init(&state, list);
+ count = eina_inlist_sorted_state_init(&state, list);
/*
* now do a dychotomic search directly inside the jump_table.
* Now do a dychotomic search between two entries inside the jump_table
*/
cur *= state.jump_div;
- inf = cur - state.jump_div;
- sup = cur + state.jump_div;
+ inf = cur - state.jump_div - 1;
+ sup = cur + state.jump_div + 1;
if (sup > count - 1) sup = count - 1;
if (inf < 0) inf = 0;
break;
}
- if (cmp < 0)
+ if (cmp <= 0)
return eina_inlist_append_relative(list, item, ct);
return eina_inlist_prepend_relative(list, item, ct);
}
int cmp = 0;
int inf, sup;
int cur = 0;
- int count = 0;
+ int count;
unsigned short head;
unsigned int offset;
return eina_inlist_prepend(list, item);
}
+ count = state->inserted;
+
/*
* now do a dychotomic search directly inside the jump_table.
*/
* Now do a dychotomic search between two entries inside the jump_table
*/
cur *= state->jump_div;
- inf = cur - state->jump_div;
- sup = cur + state->jump_div;
+ inf = cur - state->jump_div - 1;
+ sup = cur + state->jump_div + 1;
if (sup > count - 1) sup = count - 1;
- if (inf < 0)
- inf = 0;
+ if (inf < 0) inf = 0;
while (inf <= sup)
{
break;
}
- if (cmp < 0)
+ if (cmp <= 0)
{
cur++;
- head = cur / state->jump_div;
- offset = cur % state->jump_div;
ct = eina_inlist_append_relative(list, item, ct);
- _eina_inlist_sorted_state_insert(state, head, offset);
- return ct;
}
+ else
+ {
+ ct = eina_inlist_prepend_relative(list, item, ct);
+ }
+
head = cur / state->jump_div;
offset = cur % state->jump_div;
- ct = eina_inlist_prepend_relative(list, item, ct);
_eina_inlist_sorted_state_insert(state, head, offset);
return ct;
}
Eina_Test_Inlist *prev;
int i = 0;
+ fail_if(!eina_init());
+
tmp = _eina_test_inlist_build(42);
lst = eina_inlist_append(lst, EINA_INLIST_GET(tmp));
fail_if(!lst);
while (lst)
lst = eina_inlist_remove(lst, lst);
+
+ eina_shutdown();
}
END_TEST
Eina_Inlist *sorted = NULL;
int i;
+ fail_if(!eina_init());
+
srand(time(NULL));
- for (i = 0; i < 1000; ++i)
+ for (i = 0; i < 2000; ++i)
{
tmp = malloc(sizeof (Eina_Test_Inlist_Sorted));
if (!tmp) continue ;
}
_eina_test_inlist_check(sorted);
+
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_inlist_sorted_state)
+{
+ Eina_Test_Inlist_Sorted *tmp;
+ Eina_Inlist_Sorted_State *state;
+ Eina_Inlist *list = NULL;
+ int i;
+
+ fail_if(!eina_init());
+
+ state = eina_inlist_sorted_state_new();
+ fail_if(!state);
+
+ for (i = 0; i < 2000; ++i)
+ {
+ tmp = malloc(sizeof (Eina_Test_Inlist_Sorted));
+ if (!tmp) continue ;
+
+ tmp->value = rand();
+
+ list = eina_inlist_sorted_state_insert(list, EINA_INLIST_GET(tmp), _eina_test_inlist_cmp, state);
+ _eina_test_inlist_check(list);
+ }
+
+ _eina_test_inlist_check(list);
+
+ eina_inlist_sorted_state_free(state);
+
+ eina_shutdown();
}
END_TEST
{
tcase_add_test(tc, eina_inlist_simple);
tcase_add_test(tc, eina_inlist_sorted);
+ tcase_add_test(tc, eina_inlist_sorted_state);
}