From: Matthias Clasen Date: Sat, 14 Jan 2023 01:52:30 +0000 (-0500) Subject: icontheme: Keep a single string set X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~8^2~63^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=7c1a0e0c153ff99a0f2bbb82e8d3ffd9a96d835e;p=gtk4.git icontheme: Keep a single string set Instead of keeping a GtkStringSet per IconTheme, just make one for the whole GtkIconTheme. This avoids loops of the themes in some places, and due to the overlap in icon names between the themes, it reduces the amount of memory we use for the icon names with Adwaita+hicolor from 5+4 chunks to 6 chunks. --- diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 6340186fca..517a0f7819 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -130,10 +130,35 @@ struct _GtkStringSet { int used_in_chunk; }; +#ifdef G_ENABLE_DEBUG +static void +dump_string_set (GtkStringSet *set) +{ + GtkStringSetChunk *chunk = set->chunks; + unsigned int n_chunks = 0; + GHashTableIter iter; + gpointer key; + + while (chunk) + { + n_chunks++; + chunk = chunk->next; + } + g_print ("%u strings, %u chunks\n", g_hash_table_size (set->hash), n_chunks); + + g_hash_table_iter_init (&iter, set->hash); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + char *string = key; + g_print ("%s\n", string); + } +} +#endif + static void gtk_string_set_init (GtkStringSet *set) { - set->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + set->hash = g_hash_table_new (g_str_hash, g_str_equal); set->chunks = NULL; set->used_in_chunk = STRING_SET_CHUNK_SIZE; /* To trigger a grow directly */ } @@ -306,6 +331,8 @@ struct _GtkIconTheme GtkIconPaintable *lru_cache[LRU_CACHE_SIZE]; /* Protected by icon_cache lock */ int lru_cache_current; /* Protected by icon_cache lock */ + GtkStringSet icons; + char *current_theme; char **search_path; char **resource_path; @@ -409,7 +436,6 @@ typedef struct GArray *dir_sizes; /* IconThemeDirSize */ GArray *dirs; /* IconThemeDir */ - GtkStringSet icons; } IconTheme; typedef struct @@ -465,8 +491,6 @@ static GtkIconPaintable *theme_lookup_icon (IconTheme *the int size, int scale, gboolean allow_svg); -static gboolean theme_has_icon (IconTheme *theme, - const char *icon_name); static void theme_subdir_load (GtkIconTheme *self, IconTheme *theme, GKeyFile *theme_file, @@ -1358,6 +1382,7 @@ blow_themes (GtkIconTheme *self) g_list_free_full (self->themes, (GDestroyNotify) theme_destroy); g_array_set_size (self->dir_mtimes, 0); g_hash_table_destroy (self->unthemed_icons); + gtk_string_set_destroy (&self->icons); } self->themes = NULL; self->unthemed_icons = NULL; @@ -1939,6 +1964,8 @@ load_themes (GtkIconTheme *self) GStatBuf stat_buf; int j; + gtk_string_set_init (&self->icons); + if (self->current_theme) insert_theme (self, self->current_theme); @@ -2014,6 +2041,8 @@ load_themes (GtkIconTheme *self) } gdk_debug_message ("%s", s->str); g_string_free (s, TRUE); + + dump_string_set (&self->icons); } #endif } @@ -2159,10 +2188,13 @@ real_choose_icon (GtkIconTheme *self, theme = l->data; for (i = 0; icon_names[i] && icon_name_is_symbolic (icon_names[i], -1); i++) { - icon_name = icon_names[i]; - icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); - if (icon) - goto out; + icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]); + if (icon_name) + { + icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); + if (icon) + goto out; + } } } @@ -2172,10 +2204,13 @@ real_choose_icon (GtkIconTheme *self, for (i = 0; icon_names[i]; i++) { - icon_name = icon_names[i]; - icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); - if (icon) - goto out; + icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]); + if (icon_name) + { + icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); + if (icon) + goto out; + } } } @@ -2556,7 +2591,6 @@ gboolean gtk_icon_theme_has_icon (GtkIconTheme *self, const char *icon_name) { - GList *l; gboolean res = FALSE; g_return_val_if_fail (GTK_IS_ICON_THEME (self), FALSE); @@ -2566,13 +2600,10 @@ gtk_icon_theme_has_icon (GtkIconTheme *self, ensure_valid_themes (self, FALSE); - for (l = self->themes; l; l = l->next) + if (gtk_string_set_lookup (&self->icons, icon_name) != NULL) { - if (theme_has_icon (l->data, icon_name)) - { - res = TRUE; - goto out; - } + res = TRUE; + goto out; } out: @@ -2611,13 +2642,10 @@ gtk_icon_theme_has_gicon (GtkIconTheme *self, for (int i = 0; names[i]; i++) { - for (GList *l = self->themes; l; l = l->next) + if (gtk_string_set_lookup (&self->icons, names[i]) != NULL) { - if (theme_has_icon (l->data, names[i])) - { - res = TRUE; - goto out; - } + res = TRUE; + goto out; } } @@ -2663,6 +2691,7 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self, int i; GHashTable *sizes; int *result, *r; + const char *interned_icon_name; g_return_val_if_fail (GTK_IS_ICON_THEME (self), NULL); @@ -2672,10 +2701,11 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self, sizes = g_hash_table_new (g_direct_hash, g_direct_equal); + interned_icon_name = gtk_string_set_lookup (&self->icons, icon_name); + for (l = self->themes; l; l = l->next) { IconTheme *theme = l->data; - const char *interned_icon_name = gtk_string_set_lookup (&theme->icons, icon_name); for (i = 0; i < theme->dir_sizes->len; i++) { @@ -2732,25 +2762,15 @@ gtk_icon_theme_get_icon_names (GtkIconTheme *self) char **names; char *key; int i; - GList *l; gtk_icon_theme_lock (self); ensure_valid_themes (self, FALSE); icons = g_hash_table_new (g_str_hash, g_str_equal); + gtk_string_set_list (&self->icons, icons); - l = self->themes; - while (l != NULL) - { - IconTheme *theme = l->data; - gtk_string_set_list (&theme->icons, icons); - l = l->next; - } - - g_hash_table_foreach (self->unthemed_icons, - add_key_to_hash, - icons); + g_hash_table_foreach (self->unthemed_icons, add_key_to_hash, icons); names = g_new (char *, g_hash_table_size (icons) + 1); @@ -2809,7 +2829,6 @@ theme_new (const char *theme_name, theme->name = g_strdup (theme_name); theme->dir_sizes = g_array_new (FALSE, FALSE, sizeof (IconThemeDirSize)); theme->dirs = g_array_new (FALSE, FALSE, sizeof (IconThemeDir)); - gtk_string_set_init (&theme->icons); theme->display_name = g_key_file_get_locale_string (theme_file, "Icon Theme", "Name", NULL, NULL); @@ -2840,8 +2859,6 @@ theme_destroy (IconTheme *theme) theme_dir_destroy (&g_array_index (theme->dirs, IconThemeDir, i)); g_array_free (theme->dirs, TRUE); - gtk_string_set_destroy (&theme->icons); - g_free (theme); } @@ -3040,13 +3057,6 @@ theme_lookup_icon (IconTheme *theme, IconCacheFlag min_suffix; int i; - /* Its not uncommon with misses, so we do an early check which allows us do - * do a lot less work. - * We also intern the name so later hash lookups are faster. */ - icon_name = gtk_string_set_lookup (&theme->icons, icon_name); - if (icon_name == NULL) - return FALSE; - min_difference = G_MAXINT; min_dir_size = NULL; @@ -3106,13 +3116,6 @@ theme_lookup_icon (IconTheme *theme, return NULL; } -static gboolean -theme_has_icon (IconTheme *theme, - const char *icon_name) -{ - return gtk_string_set_lookup (&theme->icons, icon_name) != NULL; -} - static GHashTable * scan_directory (GtkIconTheme *self, char *full_dir,