[gnome-menus] [libmenu] Add a cache for listing the desktop files



commit 569e4835258906ca51b6b32e062cb3f860e5aeac
Author: Michael Meeks <michael meeks novell com>
Date:   Thu May 21 03:55:59 2009 +0200

    [libmenu] Add a cache for listing the desktop files
    
    When processing a layout, we get the list of desktop files from a set of
    directories. It turns out that we nearly always use the same set of
    directories, so adding a one-entry cache makes it possible to avoid
    computing things again and again.
    
    I changed Michael's patch a bit, mainly to empty the cache when the last
    GMenuTree is unref'ed.
    
    Closes: bgo#498749
---
 libmenu/entry-directories.c |   69 +++++++++++++++++++++++++++++++++++++++---
 libmenu/entry-directories.h |    7 +++-
 libmenu/gmenu-tree.c        |    6 ++--
 3 files changed, 72 insertions(+), 10 deletions(-)

diff --git a/libmenu/entry-directories.c b/libmenu/entry-directories.c
index 5df6b11..c459ff5 100644
--- a/libmenu/entry-directories.c
+++ b/libmenu/entry-directories.c
@@ -1069,6 +1069,31 @@ entry_directory_list_get_directory (EntryDirectoryList *list,
   return retval;
 }
 
+gboolean
+_entry_directory_list_compare (const EntryDirectoryList *a,
+                               const EntryDirectoryList *b)
+{
+  GList *al, *bl;
+
+  if (a == NULL && b == NULL)
+    return TRUE;
+
+  if ((a == NULL || b == NULL))
+    return FALSE;
+
+  if (a->length != b->length)
+    return FALSE;
+
+  al = a->dirs; bl = b->dirs;
+  while (al && bl && al->data == bl->data)
+    {
+      al = al->next;
+      bl = bl->next;
+    }
+
+  return (al == NULL && bl == NULL);
+}
+
 static gboolean
 get_all_func (EntryDirectory   *ed,
               DesktopEntry     *entry,
@@ -1092,14 +1117,26 @@ get_all_func (EntryDirectory   *ed,
   return TRUE;
 }
 
+static DesktopEntrySet    *entry_directory_last_set = NULL;
+static EntryDirectoryList *entry_directory_last_list = NULL;
+
 void
-entry_directory_list_get_all_desktops (EntryDirectoryList *list,
-                                       DesktopEntrySet    *set)
+_entry_directory_list_empty_desktop_cache (void)
 {
-  GList *tmp;
+  if (entry_directory_last_set != NULL)
+    desktop_entry_set_unref (entry_directory_last_set);
+  entry_directory_last_set = NULL;
 
-  menu_verbose (" Storing all of list %p in set %p\n",
-                list, set);
+  if (entry_directory_last_list != NULL)
+    entry_directory_list_unref (entry_directory_last_list);
+  entry_directory_last_list = NULL;
+}
+
+DesktopEntrySet *
+_entry_directory_list_get_all_desktops (EntryDirectoryList *list)
+{
+  GList *tmp;
+  DesktopEntrySet *set;
 
   /* The only tricky thing here is that desktop files later
    * in the search list with the same relative path
@@ -1114,6 +1151,23 @@ entry_directory_list_get_all_desktops (EntryDirectoryList *list,
    * entry)
    */
 
+  /* This method is -extremely- slow, so we have a simple
+     one-entry cache here */
+  if (_entry_directory_list_compare (list, entry_directory_last_list))
+    {
+      menu_verbose (" Hit desktop list (%p) cache\n", list);
+      return desktop_entry_set_ref (entry_directory_last_set);
+    }
+
+  if (entry_directory_last_set != NULL)
+    desktop_entry_set_unref (entry_directory_last_set);
+  if (entry_directory_last_list != NULL)
+    entry_directory_list_unref (entry_directory_last_list);
+
+  set = desktop_entry_set_new ();
+  menu_verbose (" Storing all of list %p in set %p\n",
+                list, set);
+
   tmp = g_list_last (list->dirs);
   while (tmp != NULL)
     {
@@ -1121,6 +1175,11 @@ entry_directory_list_get_all_desktops (EntryDirectoryList *list,
 
       tmp = tmp->prev;
     }
+
+  entry_directory_last_list = entry_directory_list_ref (list);
+  entry_directory_last_set = desktop_entry_set_ref (set);
+
+  return set;
 }
 
 void
diff --git a/libmenu/entry-directories.h b/libmenu/entry-directories.h
index 3df9b9a..4b1f5fb 100644
--- a/libmenu/entry-directories.h
+++ b/libmenu/entry-directories.h
@@ -52,6 +52,9 @@ EntryDirectoryList *entry_directory_list_ref   (EntryDirectoryList *list);
 void                entry_directory_list_unref (EntryDirectoryList *list);
 
 int  entry_directory_list_get_length  (EntryDirectoryList *list);
+gboolean _entry_directory_list_compare (const EntryDirectoryList *a,
+                                        const EntryDirectoryList *b);
+
 void entry_directory_list_prepend     (EntryDirectoryList *list,
                                        EntryDirectory     *ed);
 void entry_directory_list_append_list (EntryDirectoryList *list,
@@ -67,8 +70,8 @@ void entry_directory_list_remove_monitors (EntryDirectoryList        *list,
 DesktopEntry* entry_directory_list_get_directory (EntryDirectoryList *list,
                                                   const char         *relative_path);
 
-void entry_directory_list_get_all_desktops (EntryDirectoryList *list,
-                                            DesktopEntrySet    *set);
+DesktopEntrySet *_entry_directory_list_get_all_desktops (EntryDirectoryList *list);
+void             _entry_directory_list_empty_desktop_cache (void);
 
 G_END_DECLS
 
diff --git a/libmenu/gmenu-tree.c b/libmenu/gmenu-tree.c
index 48abf77..fd8318e 100644
--- a/libmenu/gmenu-tree.c
+++ b/libmenu/gmenu-tree.c
@@ -232,6 +232,8 @@ gmenu_tree_remove_from_cache (GMenuTree      *tree,
     {
       g_hash_table_destroy (gmenu_tree_cache);
       gmenu_tree_cache = NULL;
+
+      _entry_directory_list_empty_desktop_cache ();
     }
 }
 
@@ -3212,9 +3214,7 @@ process_layout (GMenuTree          *tree,
   else
     excluded_set = NULL;
 
-  entry_pool = desktop_entry_set_new ();
-  entry_directory_list_get_all_desktops (menu_layout_node_menu_get_app_dirs (layout),
-					 entry_pool);
+  entry_pool = _entry_directory_list_get_all_desktops (menu_layout_node_menu_get_app_dirs (layout));
 
   layout_iter = menu_layout_node_get_children (layout);
   while (layout_iter != NULL)



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