From a2679ce0e21d042d83473c2d293a2ee3c374ff51 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 11 Jul 2020 15:41:35 -0400 Subject: [PATCH] sor3listmodel: Add an incremental property This lets us easily compare incremental and non-incremental sorting. --- gtk/gtksor3listmodel.c | 74 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/gtk/gtksor3listmodel.c b/gtk/gtksor3listmodel.c index 9e4df637e7..0aa618eb50 100644 --- a/gtk/gtksor3listmodel.c +++ b/gtk/gtksor3listmodel.c @@ -95,6 +95,7 @@ enum { PROP_MODEL, PROP_SORTER, PROP_SORTING, + PROP_INCREMENTAL, NUM_PROPERTIES }; @@ -113,6 +114,8 @@ struct _GtkSor3ListModel gint64 start_time; guint steps; + + gboolean incremental; }; struct _GtkSor3ListModelClass @@ -355,13 +358,50 @@ gtk_sor3_list_model_start_sorting (GtkSor3ListModel *self) g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTING]); } +static void +gtk_sor3_list_model_sort_fully (GtkSor3ListModel *self) +{ + guint n_items; + guint i; + gint64 begin = g_get_monotonic_time (); + guint changed_start; + guint changed_end; + guint changed_items = 0; + + pivot_stack_set_size (&self->stack, 0); + pivot_stack_push (&self->stack, (guint)sort_array_get_size (&self->items) - 1); + self->sorted_to = 0; + + n_items = sort_array_get_size (&self->items); + + changed_start = G_MAXUINT; + changed_end = 0; + + for (i = 0; i < n_items; i++) + { + iqs (&self->items, self->sorted_to, &self->stack, self->sorter, &changed_start, &changed_end); + self->sorted_to++; + } + + if (changed_start != GTK_INVALID_LIST_POSITION) + { + changed_items = changed_end - changed_start + 1; + g_list_model_items_changed (G_LIST_MODEL (self), changed_start, changed_items, changed_items); + } + + if (GDK_PROFILER_IS_RUNNING) + gdk_profiler_add_markf (begin, g_get_monotonic_time () - begin, "quicksort", "sort fully (%u:%u)", changed_start, changed_items); +} static void gtk_sor3_list_model_resort (GtkSor3ListModel *self) { guint64 begin = g_get_monotonic_time (); gtk_sor3_list_model_stop_sorting (self); - gtk_sor3_list_model_start_sorting (self); + if (self->incremental) + gtk_sor3_list_model_start_sorting (self); + else + gtk_sor3_list_model_sort_fully (self); if (GDK_PROFILER_IS_RUNNING) gdk_profiler_add_mark (begin, g_get_monotonic_time () - begin, "resort", NULL); @@ -385,6 +425,9 @@ gtk_sor3_list_model_items_changed_cb (GListModel *model, g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items - added + removed, n_items); } +static void gtk_sor3_list_model_set_incremental (GtkSor3ListModel *self, + gboolean incremental); + static void gtk_sor3_list_model_set_property (GObject *object, guint prop_id, @@ -403,6 +446,10 @@ gtk_sor3_list_model_set_property (GObject *object, gtk_sor3_list_model_set_sorter (self, g_value_get_object (value)); break; + case PROP_INCREMENTAL: + gtk_sor3_list_model_set_incremental (self, g_value_get_boolean (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -431,6 +478,10 @@ gtk_sor3_list_model_get_property (GObject *object, g_value_set_boolean (value, self->sorting_cb != 0); break; + case PROP_INCREMENTAL: + g_value_set_boolean (value, self->incremental); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -532,6 +583,13 @@ gtk_sor3_list_model_class_init (GtkSor3ListModelClass *class) FALSE, GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY); + properties[PROP_INCREMENTAL] = + g_param_spec_boolean ("incremental", + P_("Incremental"), + P_("Whether to sort incrementally"), + FALSE, + GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties); } @@ -664,3 +722,17 @@ gtk_sor3_list_model_get_sorter (GtkSor3ListModel *self) return self->sorter; } + +static void +gtk_sor3_list_model_set_incremental (GtkSor3ListModel *self, + gboolean incremental) +{ + g_return_if_fail (GTK_IS_SOR3_LIST_MODEL (self)); + + if (self->incremental == incremental) + return; + + self->incremental = incremental; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INCREMENTAL]); +}