summaryrefslogtreecommitdiff
path: root/gtk/gtkiconcache.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2020-02-07 11:54:00 +0100
committerAlexander Larsson <alexl@redhat.com>2020-02-07 12:00:52 +0100
commitbdbafe63f96b9fc9713ff8edb094f49b2c31a713 (patch)
tree82e4caa211e72c65603019f10f3a567c06b234e1 /gtk/gtkiconcache.c
parent2be29f982d9681b563f71dfb16faa261fc3c10b5 (diff)
downloadgtk+-bdbafe63f96b9fc9713ff8edb094f49b2c31a713.tar.gz
icontheme: Optimize memory use and lookup speed by internalizing icon names
Instead of having the IconTheme have a hashtable that owns individual strings and then IconThemeDirSize have a similar hash (but with the strings owned by the other hash), we have a consecutive memory chunks where we store the icon names and then the hashtable has pointers into this. This means we can avoid a bunch of individual strdup()s in a way that is less fragmented and wastes less space. Additionally, since we do an initial lookup anyway we have the internalized icon name during lookup which means we can use g_direct_hash/equal instead of g_str_hash/equal making the lookup faster too.
Diffstat (limited to 'gtk/gtkiconcache.c')
-rw-r--r--gtk/gtkiconcache.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/gtk/gtkiconcache.c b/gtk/gtkiconcache.c
index 7c6e6dd247..e8d982a566 100644
--- a/gtk/gtkiconcache.c
+++ b/gtk/gtkiconcache.c
@@ -198,7 +198,8 @@ get_directory_index (GtkIconCache *cache,
GHashTable *
gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
- const gchar *directory)
+ const gchar *directory,
+ GtkStringSet *set)
{
gint directory_index;
guint32 hash_offset, n_buckets;
@@ -239,7 +240,7 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
{
guint32 name_offset = GET_UINT32 (cache->buffer, chain_offset + 4);
const char *name = cache->buffer + name_offset;
- char *converted_name;
+ const char *interned_name;
guint32 hash_flags = 0;
/* Icons named foo.symbolic.png are stored in the cache as "foo.symbolic" with ICON_CACHE_FLAG_PNG,
@@ -247,18 +248,20 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
* Otherwise we use the same enum values and names as on disk. */
if (g_str_has_suffix (name, ".symbolic") && (flags & ICON_CACHE_FLAG_PNG_SUFFIX) != 0)
{
+ char *converted_name = g_strndup (name, strlen (name) - 9);
+ interned_name = gtk_string_set_add (set, converted_name);
+ g_free (converted_name);
flags |= ICON_CACHE_FLAG_SYMBOLIC_PNG_SUFFIX;
flags &= ~ICON_CACHE_FLAG_PNG_SUFFIX;
- converted_name = g_strndup (name, strlen(name) - 9);
}
else
- converted_name = g_strdup (name);
+ interned_name = gtk_string_set_add (set, name);
if (!icons)
- icons = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ icons = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
- hash_flags = GPOINTER_TO_INT (g_hash_table_lookup (icons, converted_name));
- g_hash_table_replace (icons, converted_name, GUINT_TO_POINTER (hash_flags|flags));
+ hash_flags = GPOINTER_TO_INT (g_hash_table_lookup (icons, interned_name));
+ g_hash_table_replace (icons, (char *)interned_name, GUINT_TO_POINTER (hash_flags|flags));
}
chain_offset = GET_UINT32 (cache->buffer, chain_offset);