[gtk/wip/baedert/icontheme2: 2/2] icontheme: Add LRU cache back



commit 1cd759fc236729f8dc9909fcf27b46ea218d4fca
Author: Timm Bäder <mail baedert org>
Date:   Sun Sep 1 13:25:44 2019 +0200

    icontheme: Add LRU cache back

 gtk/gtkicontheme.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 5 deletions(-)
---
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index 97c8477dca..ab22a10b2c 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -130,6 +130,8 @@ typedef enum
 #define DEBUG_CACHE(args)
 #endif
 
+#define LRU_CACHE_SIZE 100
+
 typedef struct _GtkIconInfoClass    GtkIconInfoClass;
 typedef struct _GtkIconThemeClass   GtkIconThemeClass;
 typedef struct _GtkIconThemePrivate GtkIconThemePrivate;
@@ -157,6 +159,11 @@ struct _GtkIconThemePrivate
 {
   GHashTable *info_cache;
 
+  GtkIconInfo *lru_cache[LRU_CACHE_SIZE];
+  int lru_cache_size;
+  int lru_last_add;
+  guint lru_forward : 1; /* if we fill the LRU cache forwards or backwards */
+
   gchar *current_theme;
   gchar **search_path;
   gint search_path_len;
@@ -392,6 +399,45 @@ icon_info_key_equal (gconstpointer _a,
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkIconTheme, gtk_icon_theme, G_TYPE_OBJECT)
 
+static void
+add_to_lru_cache (GtkIconInfo *info)
+{
+  GtkIconTheme *theme = info->in_cache;
+  GtkIconThemePrivate *priv = gtk_icon_theme_get_instance_private (theme);
+
+  if (!theme)
+    return;
+
+  if (priv->lru_cache_size < LRU_CACHE_SIZE)
+    {
+      priv->lru_cache[priv->lru_cache_size] = g_object_ref (info);
+      priv->lru_last_add = priv->lru_cache_size;
+      priv->lru_cache_size ++;
+    }
+  else
+    {
+
+      if (priv->lru_forward)
+        {
+          g_object_unref (priv->lru_cache[priv->lru_last_add + 1]);
+          priv->lru_cache[priv->lru_last_add + 1] = g_object_ref (info);
+          priv->lru_last_add ++;
+        }
+      else
+        {
+          g_object_unref (priv->lru_cache[priv->lru_last_add - 1]);
+          priv->lru_cache[priv->lru_last_add - 1] = g_object_ref (info);
+          priv->lru_last_add --;
+        }
+    }
+
+  /* Turn around */
+  if (priv->lru_forward && priv->lru_last_add == LRU_CACHE_SIZE - 1)
+    priv->lru_forward = FALSE;
+  else if (!priv->lru_forward && priv->lru_last_add == 0)
+    priv->lru_forward = TRUE;
+}
+
 /**
  * gtk_icon_theme_new:
  * 
@@ -685,6 +731,7 @@ gtk_icon_theme_init (GtkIconTheme *icon_theme)
                                             (GDestroyNotify)icon_info_uncached);
 
   priv->custom_theme = FALSE;
+  priv->lru_forward = TRUE;
 
   xdg_data_dirs = g_get_system_data_dirs ();
   for (i = 0; xdg_data_dirs[i]; i++) ;
@@ -794,13 +841,10 @@ blow_themes (GtkIconTheme *icon_theme)
 static void
 gtk_icon_theme_finalize (GObject *object)
 {
-  GtkIconTheme *icon_theme;
-  GtkIconThemePrivate *priv;
+  GtkIconTheme *icon_theme = GTK_ICON_THEME (object);
+  GtkIconThemePrivate *priv = gtk_icon_theme_get_instance_private (icon_theme);
   int i;
 
-  icon_theme = GTK_ICON_THEME (object);
-  priv = icon_theme->priv;
-
   g_hash_table_destroy (priv->info_cache);
 
   if (priv->theme_changed_idle)
@@ -818,6 +862,9 @@ gtk_icon_theme_finalize (GObject *object)
 
   blow_themes (icon_theme);
 
+  for (i = 0; i < priv->lru_cache_size; i ++)
+    g_object_unref (priv->lru_cache[i]);
+
   G_OBJECT_CLASS (gtk_icon_theme_parent_class)->finalize (object);  
 }
 
@@ -3641,6 +3688,10 @@ icon_info_ensure_scale_and_texture (GtkIconInfo *icon_info)
     }
 
   g_assert (icon_info->texture != NULL);
+
+  /* Add to LRU cache now that icon_info has a texture */
+  add_to_lru_cache (icon_info);
+
   return TRUE;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]