forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
19bb043a85
commit
7c1a0e0c15
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user