From 8a5bb6cb5ff1bc032c5253880f2dbc934bdf6749 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 11 Feb 2020 17:30:28 -0500 Subject: [PATCH] lookup: Merge rulesets more efficiently Keep lookups sorted, and take advantage of the fact that the rulesets are sorted, too. We can merge them in a linear sweep. --- gtk/gtkcsslookup.c | 60 +++++++++++++++++++++------------------ gtk/gtkcsslookupprivate.h | 8 ++---- gtk/gtkcssprovider.c | 11 +------ 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c index bcce8d2a49..65d8e6d844 100644 --- a/gtk/gtkcsslookup.c +++ b/gtk/gtkcsslookup.c @@ -68,41 +68,45 @@ gtk_css_lookup_unref (GtkCssLookup *lookup) gtk_css_lookup_free (lookup); } -gboolean -gtk_css_lookup_is_missing (const GtkCssLookup *lookup, - guint id) -{ - gtk_internal_return_val_if_fail (lookup != NULL, FALSE); - - return !_gtk_bitmask_get (lookup->set_values, id); -} - -/** - * _gtk_css_lookup_set: - * @lookup: the lookup - * @id: id of the property to set, see _gtk_style_property_get_id() - * @section: (allow-none): The @section the value was defined in or %NULL - * @value: the “cascading value” to use +/* + * gtk_css_lookup_fill: + * @lookup: the #GtkCssLookup to populate + * @values: array of values to place into unpopulated slots in @lookup + * @n_values: the length of @values * - * Sets the @value for a given @id. No value may have been set for @id - * before. See _gtk_css_lookup_is_missing(). This function is used to - * set the “winning declaration” of a lookup. Note that for performance - * reasons @value and @section are not copied. It is your responsibility - * to ensure they are kept alive until _gtk_css_lookup_free() is called. - **/ + * Add the @values to @lookup for properties for which + * @lookup does not have a value yet. + */ void -gtk_css_lookup_set (GtkCssLookup *lookup, - guint id, - GtkCssLookupValue *value) +gtk_css_lookup_fill (GtkCssLookup *lookup, + GtkCssLookupValue *values, + guint n_values) { + int i, j; + gtk_internal_return_if_fail (lookup != NULL); - gtk_internal_return_if_fail (value != NULL); + gtk_internal_return_if_fail (values != NULL); if (!lookup->values) - lookup->values = g_ptr_array_sized_new (16); + lookup->values = g_ptr_array_sized_new (MAX (16, n_values)); - g_ptr_array_add (lookup->values, value); - lookup->set_values = _gtk_bitmask_set (lookup->set_values, id, TRUE); + for (i = 0, j = 0; j < n_values; j++, i++) + { + GtkCssLookupValue *v = NULL; + + for (; i < lookup->values->len; i++) + { + v = g_ptr_array_index (lookup->values, i); + if (v->id >= values[j].id) + break; + } + + if (i == lookup->values->len || v->id > values[j].id) + { + g_ptr_array_insert (lookup->values, i, &values[j]); + lookup->set_values = _gtk_bitmask_set (lookup->set_values, values[j].id, TRUE); + } + } } GtkCssSection * diff --git a/gtk/gtkcsslookupprivate.h b/gtk/gtkcsslookupprivate.h index 2d61d9b2c0..b7113076a4 100644 --- a/gtk/gtkcsslookupprivate.h +++ b/gtk/gtkcsslookupprivate.h @@ -46,11 +46,9 @@ GtkCssLookup * gtk_css_lookup_new (void); GtkCssLookup * gtk_css_lookup_ref (GtkCssLookup *lookup); void gtk_css_lookup_unref (GtkCssLookup *lookup); -gboolean gtk_css_lookup_is_missing (const GtkCssLookup *lookup, - guint id); -void gtk_css_lookup_set (GtkCssLookup *lookup, - guint id, - GtkCssLookupValue *value); +void gtk_css_lookup_fill (GtkCssLookup *lookup, + GtkCssLookupValue *values, + guint n_values); GtkCssSection * gtk_css_lookup_get_section (GtkCssLookup *lookup, guint id); diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index 995f9fd40f..ac8ffcabe4 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -462,7 +462,6 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider, GtkCssProvider *css_provider = GTK_CSS_PROVIDER (provider); GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider); GtkCssRuleset *ruleset; - guint j; int i; GtkArray tree_rules_array; GtkCssRuleset *rules_stack[32]; @@ -484,15 +483,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider, if (ruleset->styles == NULL) continue; - for (j = 0; j < ruleset->n_styles; j++) - { - guint id = ruleset->styles[j].id; - - if (!gtk_css_lookup_is_missing (lookup, id)) - continue; - - gtk_css_lookup_set (lookup, id, (GtkCssLookupValue *)&ruleset->styles[j]); - } + gtk_css_lookup_fill (lookup, (GtkCssLookupValue *)ruleset->styles, ruleset->n_styles); } gtk_array_free (&tree_rules_array, NULL);