Re: Performance ideas (resend) ...



And....here are the forgotten patches.
--- nautilus-2.25.92/libnautilus-private/nautilus-thumbnails.c	2009-02-24 09:02:16.000000000 -0500
+++ hacked/libnautilus-private/nautilus-thumbnails.c	2009-03-05 00:35:52.790467821 -0500
@@ -156,7 +156,7 @@
 	static GnomeDesktopThumbnailFactory *thumbnail_factory = NULL;
 
 	if (thumbnail_factory == NULL) {
-		thumbnail_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+		thumbnail_factory = gnome_desktop_thumbnail_factory_new_full (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL, FALSE);
 	}
 
 	return thumbnail_factory;
@@ -777,7 +777,7 @@
 nautilus_can_thumbnail (NautilusFile *file)
 {
 	GnomeDesktopThumbnailFactory *factory;
-	gboolean res;
+	CanThumbnail res;
 	char *uri;
 	time_t mtime;
 	char *mime_type;
@@ -794,7 +794,7 @@
 	g_free (mime_type);
 	g_free (uri);
 
-	return res;
+	return (gboolean)res;
 }
 
 gboolean
@@ -821,6 +821,18 @@
 	NautilusThumbnailInfo *existing_info;
 	GList *existing, *node;
 
+	switch (nautilus_can_thumbnail (file))
+          {
+          case CAN_NOT_THUMBNAIL:
+            return;
+          case MAYBE_THUMBNAIL:
+	     g_timeout_add_seconds (1, thumbnail_thread_notify_file_changed,
+			            g_strdup (nautilus_file_get_uri (file)));
+            return;
+          case CAN_THUMBNAIL:
+            break;
+          }
+
 	nautilus_file_set_is_thumbnailing (file, TRUE);
 
 	info = g_new0 (NautilusThumbnailInfo, 1);
--- nautilus-2.25.92/libnautilus-private/nautilus-file.c	2009-03-05 00:34:17.595188434 -0500
+++ hacked/libnautilus-private/nautilus-file.c	2009-03-05 00:21:09.291175489 -0500
@@ -3562,9 +3562,7 @@
 			   !file->details->is_thumbnailing &&
 			   (!file->details->thumbnailing_failed ||
 			    !nautilus_has_valid_failed_thumbnail (file))) {
-			if (nautilus_can_thumbnail (file)) {
 				nautilus_create_thumbnail (file);
-			}
 		}
 	}
 
diff -up gnome-desktop-2.25.92/libgnome-desktop/gnome-desktop-thumbnail.c.thumbnail gnome-desktop-2.25.92/libgnome-desktop/gnome-desktop-thumbnail.c
--- gnome-desktop-2.25.92/libgnome-desktop/gnome-desktop-thumbnail.c.thumbnail	2009-03-03 12:20:47.000000000 -0500
+++ gnome-desktop-2.25.92/libgnome-desktop/gnome-desktop-thumbnail.c	2009-03-05 01:42:27.097213468 -0500
@@ -45,19 +45,24 @@
 #include <gconf/gconf-client.h>
 #include <glib/gstdio.h>
 
-#define SECONDS_BETWEEN_STATS 10
-
 struct _GnomeDesktopThumbnailFactoryPrivate {
   char *application;
   GnomeDesktopThumbnailSize size;
 
   GMutex *lock;
 
+  gboolean preload;
+  gboolean disable_all;
   GHashTable *scripts_hash;
   guint thumbnailers_notify;
   guint reread_scheduled;
 };
 
+enum {
+  PROP_0,
+  PROP_PRELOAD
+};
+
 static void gnome_desktop_thumbnail_factory_init          (GnomeDesktopThumbnailFactory      *factory);
 static void gnome_desktop_thumbnail_factory_class_init    (GnomeDesktopThumbnailFactoryClass *class);
 
@@ -292,71 +297,142 @@ gnome_desktop_thumbnail_factory_finalize
     (* G_OBJECT_CLASS (parent_class)->finalize) (object);
 }
 
+static void
+gnome_desktop_thumbnail_factory_set_property (GObject      *object,
+                                              guint         prop_id,
+                                              const GValue *value,
+                                              GParamSpec   *pspec)
+{
+  GnomeDesktopThumbnailFactory *factory;
+  GnomeDesktopThumbnailFactoryPrivate *priv;
+  
+  factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
+  priv = factory->priv;
+
+  switch (prop_id)
+    {
+    case PROP_PRELOAD:
+      priv->preload = g_value_get_boolean (value);
+      g_print ("setting preload to %d\n", priv->preload);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gnome_desktop_thumbnail_factory_get_property (GObject    *object,
+                                              guint       prop_id,
+                                              GValue     *value,
+                                              GParamSpec *pspec)
+{
+  GnomeDesktopThumbnailFactory *factory;
+  GnomeDesktopThumbnailFactoryPrivate *priv;
+  
+  factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
+  priv = factory->priv;
+
+  switch (prop_id)
+    {
+    case PROP_PRELOAD:
+      g_value_set_boolean (value, priv->preload);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static char *
+key_to_mimetype (const char *key)
+{
+  char *mimetype, *escape;
+
+  mimetype = g_strdup (key);
+  mimetype = strrchr (mimetype, '/');
+
+  if (!mimetype)
+    return NULL;
+
+  mimetype++; /* skip past slash */
+
+  /* Convert '@' to slash in mimetype */
+  escape = strchr (mimetype, '@');
+  if (escape != NULL)
+    *escape = '/';
+
+  /* Convert any remaining '@' to '+' in mimetype */
+  while ((escape = strchr (mimetype, '@')) != NULL)
+    *escape = '+';
+
+  return mimetype;
+}
+
+static char *
+mimetype_to_key (const char *mimetype)
+{
+  char *key, *p;
+  key = g_strdup (mimetype);
+
+  p = strchr (key, '/');
+  *p = '@';
+  while ((p = strchr (p, '+')) != NULL)
+    *p = '@';
+
+  return key;
+}
+
 /* Must be called on main thread */
 static GHashTable *
-read_scripts (void)
+read_scripts (GnomeDesktopThumbnailFactory *factory)
 {
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
   GHashTable *scripts_hash;
   GConfClient *client;
   GSList *subdirs, *l;
-  char *subdir, *enable, *escape, *commandkey, *command, *mimetype;
+  char *subdir, *enable, *commandkey, *command, *mimetype;
 
   client = gconf_client_get_default ();
 
-  if (gconf_client_get_bool (client,
-			     "/desktop/gnome/thumbnailers/disable_all",
-			     NULL))
-    {
-      g_object_unref (G_OBJECT (client));
-      return NULL;
-    }
-  
+  g_print ("read_scripts\n");
   scripts_hash = g_hash_table_new_full (g_str_hash,
 					g_str_equal,
 					g_free, g_free);
 
-  
+  priv->disable_all = gconf_client_get_bool (client,
+			                     "/desktop/gnome/thumbnailers/disable_all",
+			                     NULL);
+  if (priv->disable_all)
+    {
+      g_object_unref (G_OBJECT (client));
+      return scripts_hash;
+    }
+
   subdirs = gconf_client_all_dirs (client, "/desktop/gnome/thumbnailers", NULL);
 
   for (l = subdirs; l != NULL; l = l->next)
     {
       subdir = l->data;
+      mimetype = key_to_mimetype (subdir);
+      if (mimetype)
+        {
+          command = NULL;
+          enable = g_strconcat (subdir, "/enable", NULL);
+          if (gconf_client_get_bool (client, enable, NULL))
+            {
+	      commandkey = g_strconcat (subdir, "/command", NULL);
+	      command = gconf_client_get_string (client, commandkey, NULL);
+	      g_free (commandkey);
+            }
 
-      enable = g_strdup_printf ("%s/enable", subdir);
-      if (gconf_client_get_bool (client,
-				 enable,
-				 NULL))
-	{
-	  commandkey = g_strdup_printf ("%s/command", subdir);
-	  command = gconf_client_get_string (client, commandkey, NULL);
-	  g_free (commandkey);
-
-	  if (command != NULL) {
-	    mimetype = strrchr (subdir, '/');
-	    if (mimetype != NULL)
-	      {
-		mimetype++; /* skip past slash */
-		
-		/* Convert '@' to slash in mimetype */
-		escape = strchr (mimetype, '@');
-		if (escape != NULL)
-		  *escape = '/';
-
-		/* Convert any remaining '@' to '+' in mimetype */
-		while ((escape = strchr (mimetype, '@')) != NULL)
-                  *escape = '+';
-
-		g_hash_table_insert (scripts_hash,
-				     g_strdup (mimetype), command);
-	      }
-	    else
-	      {
-		g_free (command);
-	      }
-	  }
+          if (!command)
+            command = g_strdup ("-");
+
+          g_hash_table_insert (scripts_hash, mimetype, command);
+
+          g_free (enable);
 	}
-      g_free (enable);
-      
       g_free (subdir);
     }
   
@@ -370,12 +446,77 @@ read_scripts (void)
 
 /* Must be called on main thread */
 static void
+read_script (GnomeDesktopThumbnailFactory *factory,
+             const char                   *mimetype)
+{
+  GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+  GConfClient *client;
+  char *subdir;
+  char *key;
+  char *command;
+  char *enable;
+  char *commandkey;
+
+  if (g_hash_table_lookup (priv->scripts_hash, mimetype))
+    return;
+
+  client = gconf_client_get_default ();
+
+  key = mimetype_to_key (mimetype);
+  subdir = g_strconcat ("/desktop/gnome/thumbnailers/", key, NULL);
+
+  command = NULL;
+
+  enable = g_strconcat (subdir, "/enable", NULL);
+  if (gconf_client_get_bool (client, enable, NULL))
+    {
+      commandkey = g_strconcat (subdir, "/command", NULL);
+      command = gconf_client_get_string (client, commandkey, NULL);
+      g_free (commandkey);
+    }
+
+  if (!command)
+    command = g_strdup ("-");
+
+  g_free (enable);
+  g_free (subdir);
+  g_free (key);
+  g_object_unref (client);
+
+  g_mutex_lock (priv->lock);
+
+  g_hash_table_insert (priv->scripts_hash, g_strdup (mimetype), command);
+
+  g_mutex_unlock (priv->lock);
+}
+
+typedef struct {
+  GnomeDesktopThumbnailFactory *factory;
+  char *mime_type;
+} ReadScriptData;
+
+static gboolean
+read_script_idle_callback (gpointer data)
+{
+  ReadScriptData *rsdata = data;
+
+  read_script (rsdata->factory, rsdata->mime_type);
+
+  g_object_unref (rsdata->factory);
+  g_free (rsdata->mime_type);
+  g_free (rsdata);
+
+  return FALSE;
+}
+
+/* Must be called on main thread */
+static void
 gnome_desktop_thumbnail_factory_reread_scripts (GnomeDesktopThumbnailFactory *factory)
 {
   GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
   GHashTable *scripts_hash;
 
-  scripts_hash = read_scripts ();
+  scripts_hash = read_scripts (factory);
 
   g_mutex_lock (priv->lock);
 
@@ -413,12 +554,44 @@ schedule_reread (GConfClient* client,
 
   g_mutex_lock (priv->lock);
 
-  if (priv->reread_scheduled == 0)
+  if (priv->preload)
     {
-      priv->reread_scheduled = g_idle_add (reread_idle_callback,
-					   factory);
+      if (priv->reread_scheduled == 0)
+        {
+          priv->reread_scheduled = g_idle_add (reread_idle_callback,
+	    				       factory);
+        }
     }
-  
+  else
+    {
+      const char *key;
+      char *mimetype, *s;
+      GConfValue *value;
+
+      key = gconf_entry_get_key (entry);
+      value = gconf_entry_get_value (entry);
+      if (g_str_has_prefix (key, "/desktop/gnome/thumbnailers/"))
+        {
+          key = key + strlen ("/desktop/gnome/thumbnailers/");
+          if (strcmp (key, "disable_all") == 0)
+            {
+              priv->disable_all = gconf_value_get_bool (value);
+            }
+          else
+           {
+             s = strrchr (key, '/');
+             if (s)
+               *s = 0;
+             mimetype = key_to_mimetype (key);
+             if (mimetype)
+               {
+                 g_hash_table_remove (priv->scripts_hash, mimetype);
+                 g_free (mimetype);
+               }
+           }
+        }
+    }
+
   g_mutex_unlock (priv->lock);
 }
 
@@ -426,7 +599,6 @@ schedule_reread (GConfClient* client,
 static void
 gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory)
 {
-  GConfClient *client;
   GnomeDesktopThumbnailFactoryPrivate *priv;
   
   factory->priv = g_new0 (GnomeDesktopThumbnailFactoryPrivate, 1);
@@ -435,12 +607,34 @@ gnome_desktop_thumbnail_factory_init (Gn
 
   priv->size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
   priv->application = g_strdup ("gnome-thumbnail-factory");
-  
   priv->scripts_hash = NULL;
-  
+  priv->preload = TRUE;
+  priv->disable_all = FALSE;
+
   priv->lock = g_mutex_new ();
+}
 
-  gnome_desktop_thumbnail_factory_reread_scripts (factory);
+static GObject *
+gnome_desktop_thumbnail_factory_constructor (GType                  type,
+                                             guint                  n_construct_properties,
+                                             GObjectConstructParam *construct_params)
+{
+  GConfClient *client;
+  GObject *object;
+  GnomeDesktopThumbnailFactory *factory;
+  GnomeDesktopThumbnailFactoryPrivate *priv;
+
+  object = G_OBJECT_CLASS (gnome_desktop_thumbnail_factory_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+  factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
+  priv = factory->priv;
+
+  if (priv->preload)
+    gnome_desktop_thumbnail_factory_reread_scripts (factory);
+  else
+    priv->scripts_hash = g_hash_table_new_full (g_str_hash,
+					        g_str_equal,
+					        g_free, g_free);
 
   client = gconf_client_get_default ();
   gconf_client_add_dir (client,
@@ -451,7 +645,9 @@ gnome_desktop_thumbnail_factory_init (Gn
 						       schedule_reread, factory, NULL,
 						       NULL);
 
-  g_object_unref (G_OBJECT (client));
+  g_object_unref (client);
+
+  return object;
 }
 
 static void
@@ -462,6 +658,16 @@ gnome_desktop_thumbnail_factory_class_in
   gobject_class = G_OBJECT_CLASS (class);
 	
   gobject_class->finalize = gnome_desktop_thumbnail_factory_finalize;
+  gobject_class->set_property = gnome_desktop_thumbnail_factory_set_property;
+  gobject_class->get_property = gnome_desktop_thumbnail_factory_get_property;
+  gobject_class->constructor = gnome_desktop_thumbnail_factory_constructor;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_PRELOAD,
+                                   g_param_spec_boolean ("preload",
+                                                         NULL, NULL,
+                                                         TRUE,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 /**
@@ -481,7 +687,23 @@ gnome_desktop_thumbnail_factory_new (Gno
 {
   GnomeDesktopThumbnailFactory *factory;
   
-  factory = g_object_new (GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY, NULL);
+  factory = g_object_new (GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY,
+                          "preload", TRUE, NULL);
+  
+  g_print ("gnome_desktop_thumbnail_factory_new\n");
+  factory->priv->size = size;
+  
+  return factory;
+}
+
+GnomeDesktopThumbnailFactory *
+gnome_desktop_thumbnail_factory_new_full (GnomeDesktopThumbnailSize size,
+                                          gboolean                  preload)
+{
+  GnomeDesktopThumbnailFactory *factory;
+  
+  factory = g_object_new (GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY,
+                          "preload", preload, NULL);
   
   factory->priv->size = size;
   
@@ -662,29 +884,55 @@ mimetype_supported_by_gdk_pixbuf (const 
  *
  * Since: 2.2
  **/
-gboolean
+CanThumbnail
 gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *factory,
 					       const char            *uri,
 					       const char            *mime_type,
 					       time_t                 mtime)
 {
+  char *command;
+
   /* Don't thumbnail thumbnails */
   if (uri &&
       strncmp (uri, "file:/", 6) == 0 &&
       strstr (uri, "/.thumbnails/") != NULL)
-    return FALSE;
-  
-  if (mime_type != NULL &&
-      (mimetype_supported_by_gdk_pixbuf (mime_type) ||
-       (factory->priv->scripts_hash != NULL &&
-	g_hash_table_lookup (factory->priv->scripts_hash, mime_type))))
-    {
-      return !gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (factory,
-								  uri,
-								  mtime);
+    return CAN_NOT_THUMBNAIL;
+
+  if (!mime_type)
+    return CAN_NOT_THUMBNAIL;
+
+  if (mimetype_supported_by_gdk_pixbuf (mime_type))
+    goto out;
+
+  if (factory->priv->disable_all)
+    return CAN_NOT_THUMBNAIL;
+
+  command = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
+  if (!command)
+    {
+      if (factory->priv->preload)
+        return CAN_NOT_THUMBNAIL;
+      else
+        {
+          ReadScriptData *data;
+g_print ("maybe can thumbnail %s %s\n", uri, mime_type);
+          data = g_new (ReadScriptData, 1);
+          data->factory = g_object_ref (factory);
+          data->mime_type = g_strdup (mime_type);
+          g_idle_add (read_script_idle_callback, data);
+          return MAYBE_THUMBNAIL;
+        }
     }
-  
-  return FALSE;
+  else if (strcmp (command, "-") == 0)
+    return CAN_NOT_THUMBNAIL;
+
+out:
+  if (gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (factory,
+							          uri,
+								  mtime))
+    return CAN_NOT_THUMBNAIL;
+  else
+    return CAN_THUMBNAIL;
 }
 
 static char *
@@ -798,9 +1046,14 @@ gnome_desktop_thumbnail_factory_generate
   pixbuf = NULL;
 
   script = NULL;
-  if (factory->priv->scripts_hash != NULL)
-    script = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
-  
+  if (!factory->priv->disable_all)
+    {
+      if (factory->priv->scripts_hash != NULL)
+        script = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
+      if (script && strcmp (script, "-") == 0)
+        script = NULL;
+    }
+
   if (script)
     {
       int fd;
diff -up gnome-desktop-2.25.92/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h.thumbnail gnome-desktop-2.25.92/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h
--- gnome-desktop-2.25.92/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h.thumbnail	2009-03-03 12:20:47.000000000 -0500
+++ gnome-desktop-2.25.92/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h	2009-03-05 00:36:44.076454161 -0500
@@ -64,6 +64,7 @@ struct _GnomeDesktopThumbnailFactoryClas
 
 GType                  gnome_desktop_thumbnail_factory_get_type (void);
 GnomeDesktopThumbnailFactory *gnome_desktop_thumbnail_factory_new      (GnomeDesktopThumbnailSize     size);
+GnomeDesktopThumbnailFactory *gnome_desktop_thumbnail_factory_new_full (GnomeDesktopThumbnailSize     size, gboolean preload_scripts);
 
 char *                 gnome_desktop_thumbnail_factory_lookup   (GnomeDesktopThumbnailFactory *factory,
 								 const char            *uri,
@@ -72,7 +73,13 @@ char *                 gnome_desktop_thu
 gboolean               gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (GnomeDesktopThumbnailFactory *factory,
 										   const char            *uri,
 										   time_t                 mtime);
-gboolean               gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *factory,
+typedef enum {
+ CAN_NOT_THUMBNAIL,
+ CAN_THUMBNAIL,
+ MAYBE_THUMBNAIL
+} CanThumbnail;
+
+CanThumbnail           gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *factory,
 								      const char            *uri,
 								      const char            *mime_type,
 								      time_t                 mtime);
@@ -87,7 +94,6 @@ void                   gnome_desktop_thu
 										const char            *uri,
 										time_t                 mtime);
 
-
 /* Thumbnailing utils: */
 gboolean   gnome_desktop_thumbnail_has_uri           (GdkPixbuf          *pixbuf,
 						      const char         *uri);


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