forked from AuroraMiddleware/gtk
sortlistmodel: Properly compute runs
When updating a (partially) sorted model, take the known runs for the existing sort and apply them to the new sort. That way, we don't have to check the whole model again. Benchmarks: appending half the items to a model of strings old new 512,000 items 437ms 389ms 1,024,000 items 1006ms 914ms appending 10% of the items to a model of strings old new 512,000 items 206ms 132ms 1,024,000 items 438ms 301ms appending 1 item to a model of strings old new 64,000 items 1.8ms 0.00ms 512,000 items --- 0.01ms
This commit is contained in:
parent
c03383d3e5
commit
bf5c540357
@ -414,6 +414,7 @@ gtk_sort_list_model_update_items (GtkSortListModel *self,
|
||||
guint *unmodified_end)
|
||||
{
|
||||
guint i, n_items, valid;
|
||||
guint run_index, valid_run, valid_run_end, run_end;
|
||||
guint start, end;
|
||||
gpointer *old_keys;
|
||||
|
||||
@ -445,28 +446,50 @@ gtk_sort_list_model_update_items (GtkSortListModel *self,
|
||||
|
||||
/* then, update the positions */
|
||||
valid = 0;
|
||||
for (i = 0; i < n_items; i++)
|
||||
valid_run = 0;
|
||||
valid_run_end = 0;
|
||||
run_index = 0;
|
||||
run_end = 0;
|
||||
for (i = 0; i < n_items;)
|
||||
{
|
||||
guint pos = ((char *) self->positions[i] - (char *) old_keys) / self->key_size;
|
||||
|
||||
if (pos >= position + removed)
|
||||
pos = pos - removed + added;
|
||||
else if (pos >= position)
|
||||
{
|
||||
start = MIN (start, valid);
|
||||
end = n_items - i - 1;
|
||||
continue;
|
||||
if (runs[run_index] == 0)
|
||||
{
|
||||
run_end = n_items;
|
||||
valid_run_end = G_MAXUINT;
|
||||
}
|
||||
else
|
||||
{
|
||||
run_end += runs[run_index++];
|
||||
}
|
||||
|
||||
self->positions[valid] = key_from_pos (self, pos);
|
||||
valid++;
|
||||
for (; i < run_end; i++)
|
||||
{
|
||||
guint pos = ((char *) self->positions[i] - (char *) old_keys) / self->key_size;
|
||||
|
||||
if (pos >= position + removed)
|
||||
pos = pos - removed + added;
|
||||
else if (pos >= position)
|
||||
{
|
||||
start = MIN (start, valid);
|
||||
end = n_items - i - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
self->positions[valid] = key_from_pos (self, pos);
|
||||
valid++;
|
||||
}
|
||||
|
||||
if (valid_run_end < valid)
|
||||
{
|
||||
runs[valid_run++] = valid - valid_run_end;
|
||||
valid_run_end = valid;
|
||||
}
|
||||
}
|
||||
self->positions = g_renew (gpointer, self->positions, n_items - removed + added);
|
||||
|
||||
/* FIXME */
|
||||
runs[0] = 0;
|
||||
|
||||
g_assert (i == n_items);
|
||||
g_assert (valid == n_items - removed);
|
||||
runs[valid_run] = 0;
|
||||
|
||||
self->positions = g_renew (gpointer, self->positions, n_items - removed + added);
|
||||
|
||||
self->n_items = n_items - removed + added;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user