timsort: Add gtk_tim_sort_set_already_sorted()
... and use it in Tim1SortModel
This commit is contained in:
@@ -175,13 +175,22 @@ sort_func (gconstpointer a,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tim1_sort_model_resort (GtkTim1SortModel *self)
|
||||
gtk_tim1_sort_model_resort (GtkTim1SortModel *self,
|
||||
guint already_sorted)
|
||||
{
|
||||
gtk_tim_sort (sort_array_get_data (&self->items),
|
||||
sort_array_get_size (&self->items),
|
||||
sizeof (SortItem),
|
||||
sort_func,
|
||||
self->sorter);
|
||||
GtkTimSort sort;
|
||||
|
||||
gtk_tim_sort_init (&sort,
|
||||
sort_array_get_data (&self->items),
|
||||
sort_array_get_size (&self->items),
|
||||
sizeof (SortItem),
|
||||
sort_func,
|
||||
self->sorter);
|
||||
gtk_tim_sort_set_already_sorted (&sort, already_sorted);
|
||||
|
||||
while (gtk_tim_sort_step (&sort));
|
||||
|
||||
gtk_tim_sort_finish (&sort);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -252,7 +261,7 @@ gtk_tim1_sort_model_items_changed_cb (GListModel *model,
|
||||
{
|
||||
sort_array_append (&self->items, &(SortItem) { g_list_model_get_item (self->model, i), i });
|
||||
}
|
||||
gtk_tim1_sort_model_resort (self);
|
||||
gtk_tim1_sort_model_resort (self, sort_array_get_size (&self->items) - added);
|
||||
|
||||
for (i = 0; i < start; i++)
|
||||
{
|
||||
@@ -339,7 +348,7 @@ gtk_tim1_sort_model_sorter_changed_cb (GtkSorter *sorter,
|
||||
else if (sort_array_is_empty (&self->items))
|
||||
gtk_tim1_sort_model_create_items (self);
|
||||
|
||||
gtk_tim1_sort_model_resort (self);
|
||||
gtk_tim1_sort_model_resort (self, 0);
|
||||
|
||||
n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
if (n_items > 1)
|
||||
@@ -476,7 +485,7 @@ gtk_tim1_sort_model_set_model (GtkTim1SortModel *self,
|
||||
added = g_list_model_get_n_items (model);
|
||||
|
||||
gtk_tim1_sort_model_create_items (self);
|
||||
gtk_tim1_sort_model_resort (self);
|
||||
gtk_tim1_sort_model_resort (self, 0);
|
||||
}
|
||||
else
|
||||
added = 0;
|
||||
|
||||
@@ -215,10 +215,6 @@ gtk_tim_sort(merge_append) (GtkTimSort *self)
|
||||
/* Push run onto pending-run stack, and maybe merge */
|
||||
gtk_tim_sort_push_run (self, self->base, run_len);
|
||||
|
||||
/* Advance to find next run */
|
||||
self->base = ELEM (self->base, run_len);
|
||||
self->size -= run_len;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,10 @@ gtk_tim_sort_push_run (GtkTimSort *self,
|
||||
self->run[self->pending_runs].base = base;
|
||||
self->run[self->pending_runs].len = len;
|
||||
self->pending_runs++;
|
||||
|
||||
/* Advance to find next run */
|
||||
self->base = ((char *) self->base) + len * self->element_size;
|
||||
self->size -= len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,6 +171,18 @@ gtk_tim_sort_ensure_capacity (GtkTimSort *self,
|
||||
return self->tmp;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tim_sort_set_already_sorted (GtkTimSort *self,
|
||||
gsize already_sorted)
|
||||
{
|
||||
g_assert (self);
|
||||
g_assert (self->pending_runs == 0);
|
||||
g_assert (already_sorted <= self->size);
|
||||
|
||||
if (already_sorted > 1)
|
||||
gtk_tim_sort_push_run (self, self->base, already_sorted);
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define WIDTH 4
|
||||
#include "gtktimsort-impl.c"
|
||||
|
||||
@@ -95,6 +95,8 @@ void gtk_tim_sort_init (GtkTimSort
|
||||
gpointer data);
|
||||
void gtk_tim_sort_finish (GtkTimSort *self);
|
||||
|
||||
void gtk_tim_sort_set_already_sorted (GtkTimSort *self,
|
||||
gsize already_sorted);
|
||||
gboolean gtk_tim_sort_step (GtkTimSort *self);
|
||||
|
||||
void gtk_tim_sort (gpointer base,
|
||||
|
||||
Reference in New Issue
Block a user