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.
This commit is contained in:
Matthias Clasen
2020-02-11 17:30:28 -05:00
parent 05376fca63
commit 8a5bb6cb5f
3 changed files with 36 additions and 43 deletions

View File

@@ -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 *

View File

@@ -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);

View File

@@ -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);