lookup: Don't store flat arrays

Most lookups have no or just a few values.
We can drastically reduce the amount of memory used for lookups,
and then we can afford to keep them around and avoid some lookups
in the future.
This commit is contained in:
Matthias Clasen
2020-02-10 18:22:17 -05:00
parent 6fb18b74b4
commit e34d7d07b1
2 changed files with 40 additions and 5 deletions

View File

@@ -24,6 +24,16 @@
#include "gtkprivatetypebuiltins.h"
#include "gtkprivate.h"
static void
free_value (gpointer data)
{
GtkCssLookupValue *value = data;
gtk_css_value_unref (value->value);
if (value->section)
gtk_css_section_unref (value->section);
}
GtkCssLookup *
gtk_css_lookup_new (void)
{
@@ -39,6 +49,8 @@ static void
gtk_css_lookup_free (GtkCssLookup *lookup)
{
_gtk_bitmask_free (lookup->set_values);
if (lookup->values)
g_array_unref (lookup->values);
g_free (lookup);
}
@@ -93,11 +105,21 @@ gtk_css_lookup_set (GtkCssLookup *lookup,
GtkCssSection *section,
GtkCssValue *value)
{
GtkCssLookupValue v;
gtk_internal_return_if_fail (lookup != NULL);
gtk_internal_return_if_fail (value != NULL);
gtk_internal_return_if_fail (lookup->values[id].value == NULL);
lookup->values[id].value = value;
lookup->values[id].section = section;
v.value = gtk_css_value_ref (value);
v.section = section ? gtk_css_section_ref (section) : NULL;
v.id = id;
if (!lookup->values)
{
lookup->values = g_array_sized_new (FALSE, FALSE, sizeof (GtkCssLookupValue), 16);
g_array_set_clear_func (lookup->values, free_value);
}
g_array_append_val (lookup->values, v);
lookup->set_values = _gtk_bitmask_set (lookup->set_values, id, TRUE);
}

View File

@@ -33,12 +33,13 @@ typedef struct _GtkCssLookup GtkCssLookup;
typedef struct {
GtkCssSection *section;
GtkCssValue *value;
guint id;
} GtkCssLookupValue;
struct _GtkCssLookup {
int ref_count;
GtkBitmask *set_values;
GtkCssLookupValue values[GTK_CSS_PROPERTY_N_PROPERTIES];
GArray *values;
};
GtkCssLookup * gtk_css_lookup_new (void);
@@ -62,7 +63,19 @@ static inline GtkCssLookupValue *
gtk_css_lookup_get (GtkCssLookup *lookup,
guint id)
{
return &lookup->values[id];
if (_gtk_bitmask_get (lookup->set_values, id))
{
int i;
for (i = 0; i < lookup->values->len; i++)
{
GtkCssLookupValue *value = &g_array_index (lookup->values, GtkCssLookupValue, i);
if (value->id == id)
return value;
}
}
return NULL;
}
G_END_DECLS