[gnome-software] De-duplicate any application instances



commit 4c1bbd29245b547691636105a512fa0e2247fa5c
Author: Richard Hughes <richard hughsie com>
Date:   Fri Aug 30 12:41:34 2013 +0100

    De-duplicate any application instances
    
    This means if the same app is installed in one tab then the status is changed
    in other tabs.

 src/gs-plugin-loader.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/gs-plugin-loader.h |    2 +
 src/gs-self-test.c     |   28 ++++++++++++++++++++++
 3 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 1b14cff..b93c7e0 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -36,6 +36,7 @@ struct GsPluginLoaderPrivate
        gchar                   *location;
        GsPluginStatus           status_last;
        GPtrArray               *pending_apps;
+       GHashTable              *app_cache;
 };
 
 G_DEFINE_TYPE (GsPluginLoader, gs_plugin_loader, G_TYPE_OBJECT)
@@ -62,6 +63,50 @@ gs_plugin_loader_error_quark (void)
 }
 
 /**
+ * gs_plugin_loader_dedupe:
+ */
+GsApp *
+gs_plugin_loader_dedupe (GsPluginLoader *plugin_loader, GsApp *app)
+{
+       GsApp *new_app;
+       GsPluginLoaderPrivate *priv = plugin_loader->priv;
+
+       /* already exists */
+       new_app = g_hash_table_lookup (priv->app_cache, gs_app_get_id (app));
+       if (new_app != NULL) {
+               /* this looks a little odd to unref the method parameter,
+                * but it allows us to do:
+                * app = gs_plugin_loader_dedupe (cache, app);
+                */
+               g_debug ("deduped %s", gs_app_get_id (app));
+               g_object_unref (app);
+               g_object_ref (new_app);
+               goto out;
+       }
+
+       /* insert new entry */
+       g_hash_table_insert (priv->app_cache,
+                            (gpointer) gs_app_get_id (app),
+                            g_object_ref (app));
+
+       /* no ref */
+       new_app = app;
+out:
+       return new_app;
+}
+
+/**
+ * gs_plugin_loader_list_dedupe:
+ **/
+static void
+gs_plugin_loader_list_dedupe (GsPluginLoader *plugin_loader, GList *list)
+{
+       GList *l;
+       for (l = list; l != NULL; l = l->next)
+               l->data = gs_plugin_loader_dedupe (plugin_loader, GS_APP (l->data));
+}
+
+/**
  * gs_plugin_loader_run_refine:
  **/
 static gboolean
@@ -156,6 +201,9 @@ gs_plugin_loader_run_results (GsPluginLoader *plugin_loader,
                         g_timer_elapsed (plugin->timer, NULL) * 1000);
        }
 
+       /* dedupe applications we already know about */
+       gs_plugin_loader_list_dedupe (plugin_loader, list);
+
        /* run refine() on each one */
        ret = gs_plugin_loader_run_refine (plugin_loader,
                                           list,
@@ -318,6 +366,9 @@ cd_plugin_loader_get_updates_thread_cb (GSimpleAsyncResult *res,
                goto out;
        }
 
+       /* dedupe applications we already know about */
+       gs_plugin_loader_list_dedupe (plugin_loader, state->list);
+
        /* coalesce all packages down into one os-update */
        for (l = state->list; l != NULL; l = l->next) {
                app_tmp = GS_APP (l->data);
@@ -798,6 +849,9 @@ cd_plugin_loader_search_thread_cb (GSimpleAsyncResult *res,
                         g_timer_elapsed (plugin->timer, NULL) * 1000);
        }
 
+       /* dedupe applications we already know about */
+       gs_plugin_loader_list_dedupe (plugin_loader, state->list);
+
        /* run refine() on each one */
        ret = gs_plugin_loader_run_refine (plugin_loader,
                                           state->list,
@@ -1422,6 +1476,10 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        plugin_loader->priv->plugins = g_ptr_array_new_with_free_func ((GDestroyNotify) 
gs_plugin_loader_plugin_free);
        plugin_loader->priv->status_last = GS_PLUGIN_STATUS_LAST;
        plugin_loader->priv->pending_apps = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
+       plugin_loader->priv->app_cache = g_hash_table_new_full (g_str_hash,
+                                                                g_str_equal,
+                                                                NULL,
+                                                                (GFreeFunc) g_object_unref);
 }
 
 /**
@@ -1443,6 +1501,7 @@ gs_plugin_loader_finalize (GObject *object)
        /* run the plugins */
        gs_plugin_loader_run (plugin_loader, "gs_plugin_destroy");
 
+       g_hash_table_unref (plugin_loader->priv->app_cache);
        g_ptr_array_unref (plugin_loader->priv->pending_apps);
        g_ptr_array_unref (plugin_loader->priv->plugins);
        g_free (plugin_loader->priv->location);
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 069d4f7..27637d8 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -132,6 +132,8 @@ gboolean     gs_plugin_loader_app_set_rating        (GsPluginLoader *plugin_loader,
 GsAppState      gs_plugin_loader_get_state_for_app     (GsPluginLoader *plugin_loader,
                                                         GsApp          *app);
 GPtrArray      *gs_plugin_loader_get_pending           (GsPluginLoader *plugin_loader);
+GsApp          *gs_plugin_loader_dedupe                (GsPluginLoader *plugin_loader,
+                                                        GsApp          *app);
 
 G_END_DECLS
 
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 4f527a2..33d79e4 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -54,6 +54,33 @@ gs_plugin_loader_status_changed_cb (GsPluginLoader *plugin_loader,
 }
 
 static void
+gs_plugin_loader_dedupe_func (void)
+{
+       GsApp *app1;
+       GsApp *app2;
+       GsPluginLoader *loader;
+
+       loader = gs_plugin_loader_new ();
+
+       /* add app */
+       app1 = gs_app_new ("app1");
+       gs_app_set_description (app1, "description");
+       app1 = gs_plugin_loader_dedupe (loader, app1);
+       g_assert_cmpstr (gs_app_get_id (app1), ==, "app1");
+       g_assert_cmpstr (gs_app_get_description (app1), ==, "description");
+
+       app2 = gs_app_new ("app1");
+       app2 = gs_plugin_loader_dedupe (loader, app2);
+       g_assert_cmpstr (gs_app_get_id (app2), ==, "app1");
+       g_assert_cmpstr (gs_app_get_description (app2), ==, "description");
+
+       g_object_unref (app1);
+       g_object_unref (app2);
+
+       g_object_unref (loader);
+}
+
+static void
 gs_plugin_loader_func (void)
 {
        gboolean ret;
@@ -197,6 +224,7 @@ main (int argc, char **argv)
 
        /* tests go here */
        g_test_add_func ("/gnome-software/app", gs_app_func);
+       g_test_add_func ("/gnome-software/plugin-loader{dedupe}", gs_plugin_loader_dedupe_func);
        g_test_add_func ("/gnome-software/plugin-loader", gs_plugin_loader_func);
 
        return g_test_run ();


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