[gnome-software/wip/hughsie/appstream-editor] Allow using a hash to deduplicate cache entries



commit 75a2a73fb011c3cfc41e233409750a21a47ae662
Author: Richard Hughes <richard hughsie com>
Date:   Fri May 5 20:54:30 2017 +0100

    Allow using a hash to deduplicate cache entries
    
    Use the full resource string as the hash to deduplicate resources with the
    same basename.

 lib/gs-self-test.c |   28 ++++++++++++++++++++++++++++
 lib/gs-utils.c     |   21 ++++++++++++++++++---
 lib/gs-utils.h     |    3 ++-
 3 files changed, 48 insertions(+), 4 deletions(-)
---
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index 65bab6d..85ba013 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -89,6 +89,33 @@ gs_os_release_func (void)
 }
 
 static void
+gs_utils_cache_func (void)
+{
+       g_autofree gchar *fn1 = NULL;
+       g_autofree gchar *fn2 = NULL;
+       g_autoptr(GError) error = NULL;
+
+       fn1 = gs_utils_get_cache_filename ("test",
+                                          "http://www.foo.bar/baz";,
+                                          GS_UTILS_CACHE_FLAG_WRITEABLE,
+                                          &error);
+       g_assert_no_error (error);
+       g_assert_cmpstr (fn1, !=, NULL);
+       g_assert (g_str_has_prefix (fn1, g_get_user_cache_dir ()));
+       g_assert (g_str_has_suffix (fn1, "test/baz"));
+
+       fn2 = gs_utils_get_cache_filename ("test",
+                                          "http://www.foo.bar/baz";,
+                                          GS_UTILS_CACHE_FLAG_WRITEABLE |
+                                          GS_UTILS_CACHE_FLAG_USE_HASH,
+                                          &error);
+       g_assert_no_error (error);
+       g_assert_cmpstr (fn2, !=, NULL);
+       g_assert (g_str_has_prefix (fn2, g_get_user_cache_dir ()));
+       g_assert (g_str_has_suffix (fn2, "test/295099f59d12b3eb0b955325fcb699cd23792a89-baz"));
+}
+
+static void
 gs_utils_error_func (void)
 {
        guint i;
@@ -521,6 +548,7 @@ main (int argc, char **argv)
        g_test_add_func ("/gnome-software/lib/utils{url}", gs_utils_url_func);
        g_test_add_func ("/gnome-software/lib/utils{wilson}", gs_utils_wilson_func);
        g_test_add_func ("/gnome-software/lib/utils{error}", gs_utils_error_func);
+       g_test_add_func ("/gnome-software/lib/utils{cache}", gs_utils_cache_func);
        g_test_add_func ("/gnome-software/lib/os-release", gs_os_release_func);
        g_test_add_func ("/gnome-software/lib/app", gs_app_func);
        g_test_add_func ("/gnome-software/lib/app{addons}", gs_app_addons_func);
diff --git a/lib/gs-utils.c b/lib/gs-utils.c
index a6e5090..002e54f 100644
--- a/lib/gs-utils.c
+++ b/lib/gs-utils.c
@@ -125,7 +125,7 @@ gs_utils_filename_array_return_newest (GPtrArray *array)
 /**
  * gs_utils_get_cache_filename:
  * @kind: A cache kind, e.g. "firmware" or "screenshots/123x456"
- * @basename: A filename basename, e.g. "system.bin"
+ * @resource: A resource, e.g. "system.bin" or "http://foo.bar/baz.bin";
  * @flags: Some #GsUtilsCacheFlags, e.g. %GS_UTILS_CACHE_FLAG_WRITEABLE
  * @error: A #GError, or %NULL
  *
@@ -133,6 +133,9 @@ gs_utils_filename_array_return_newest (GPtrArray *array)
  * This may be per-system or per-user, the latter being more likely
  * when %GS_UTILS_CACHE_FLAG_WRITEABLE is specified in @flags.
  *
+ * If %GS_UTILS_CACHE_FLAG_USE_HASH is set in @flags then the returned filename
+ * will contain the hashed version of @resource.
+ *
  * If there is more than one match, the file that has been modified last is
  * returned.
  *
@@ -140,16 +143,28 @@ gs_utils_filename_array_return_newest (GPtrArray *array)
  **/
 gchar *
 gs_utils_get_cache_filename (const gchar *kind,
-                            const gchar *basename,
-                            GsUtilsCacheFlags flags, /* ignored */
+                            const gchar *resource,
+                            GsUtilsCacheFlags flags,
                             GError **error)
 {
+       g_autofree gchar *basename = NULL;
        g_autofree gchar *cachedir = NULL;
        g_autofree gchar *vername = NULL;
        g_auto(GStrv) version = g_strsplit (VERSION, ".", 3);
        g_autoptr(GFile) cachedir_file = NULL;
        g_autoptr(GPtrArray) candidates = g_ptr_array_new_with_free_func (g_free);
 
+       /* get basename */
+       basename = g_path_get_basename (resource);
+       if (flags & GS_UTILS_CACHE_FLAG_USE_HASH) {
+               g_autofree gchar *basename_tmp = g_path_get_basename (resource);
+               g_autofree gchar *hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1,
+                                                                       resource, -1);
+               basename = g_strdup_printf ("%s-%s", hash, basename_tmp);
+       } else {
+               basename = g_path_get_basename (resource);
+       }
+
        /* not writable, so try the system cache first */
        if ((flags & GS_UTILS_CACHE_FLAG_WRITEABLE) == 0) {
                g_autofree gchar *cachefn = NULL;
diff --git a/lib/gs-utils.h b/lib/gs-utils.h
index a4e1fb9..17a0731 100644
--- a/lib/gs-utils.h
+++ b/lib/gs-utils.h
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
 typedef enum {
        GS_UTILS_CACHE_FLAG_NONE        = 0,
        GS_UTILS_CACHE_FLAG_WRITEABLE   = 1 << 0,
+       GS_UTILS_CACHE_FLAG_USE_HASH    = 1 << 1,
        /*< private >*/
        GS_UTILS_CACHE_FLAG_LAST
 } GsUtilsCacheFlags;
@@ -55,7 +56,7 @@ gboolean       gs_utils_unlink                (const gchar    *filename,
 gboolean        gs_mkdir_parent                (const gchar    *path,
                                                 GError         **error);
 gchar          *gs_utils_get_cache_filename    (const gchar    *kind,
-                                                const gchar    *basename,
+                                                const gchar    *resource,
                                                 GsUtilsCacheFlags flags,
                                                 GError         **error);
 gchar          *gs_utils_get_user_hash         (GError         **error);


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