summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2016-05-13 13:07:43 +0200
committerAlexander Larsson <alexl@redhat.com>2016-05-13 13:15:45 +0200
commit392f80a4aa81c6e89a545a3db4018fc504bc5ee1 (patch)
treef2fd3bb8da93e159acba10f41224562752e485a7
parentfa6e6c51ef30f7b994dffa5e2fae721c1d3a9a0d (diff)
downloadxdg-app-392f80a4aa81c6e89a545a3db4018fc504bc5ee1.tar.gz
FlatpakDir: Add in-memory summary cache
Remote summary files are cached for 5 minutes.
-rw-r--r--common/flatpak-dir.c113
1 files changed, 112 insertions, 1 deletions
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index c4a284d..85a0e0f 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -40,10 +40,21 @@
#define NO_SYSTEM_HELPER ((FlatpakSystemHelper *) (gpointer) 1)
+#define SUMMARY_CACHE_TIMEOUT_SEC 5*60
+
static OstreeRepo * flatpak_dir_create_system_child_repo (FlatpakDir *self,
GLnxLockFile *file_lock,
GError **error);
+
+typedef struct
+{
+ GBytes *bytes;
+ char *remote;
+ char *url;
+ guint64 time;
+} CachedSummary;
+
struct FlatpakDir
{
GObject parent;
@@ -54,6 +65,8 @@ struct FlatpakDir
FlatpakSystemHelper *system_helper;
+ GHashTable *summary_cache;
+
SoupSession *soup_session;
};
@@ -267,6 +280,7 @@ flatpak_dir_finalize (GObject *object)
g_clear_object (&self->system_helper);
g_clear_object (&self->soup_session);
+ g_clear_pointer (&self->summary_cache, g_hash_table_unref);
G_OBJECT_CLASS (flatpak_dir_parent_class)->finalize (object);
}
@@ -3650,6 +3664,82 @@ flatpak_dir_get_if_deployed (FlatpakDir *self,
return NULL;
}
+G_LOCK_DEFINE_STATIC (cache);
+
+static void
+cached_summary_free (CachedSummary *summary)
+{
+ g_bytes_unref (summary->bytes);
+ g_free (summary->remote);
+ g_free (summary->url);
+ g_free (summary);
+}
+
+static CachedSummary *
+cached_summary_new (GBytes *bytes,
+ const char *remote,
+ const char *url)
+{
+ CachedSummary *summary = g_new0 (CachedSummary, 1);
+ summary->bytes = g_bytes_ref (bytes);
+ summary->url = g_strdup (url);
+ summary->remote = g_strdup (remote);
+ summary->time = g_get_monotonic_time ();
+ return summary;
+}
+
+static GBytes *
+flatpak_dir_lookup_cached_summary (FlatpakDir *self,
+ const char *name,
+ const char *url)
+{
+ CachedSummary *summary;
+ GBytes *res = NULL;
+
+ G_LOCK (cache);
+
+ if (self->summary_cache == NULL)
+ self->summary_cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)cached_summary_free);
+
+ summary = g_hash_table_lookup (self->summary_cache, name);
+ if (summary)
+ {
+ guint64 now = g_get_monotonic_time ();
+ if ((now - summary->time) < (1000 * (SUMMARY_CACHE_TIMEOUT_SEC)) &&
+ strcmp (url, summary->url) == 0)
+ {
+ g_debug ("Using cached summary for remote %s", name);
+ res = g_bytes_ref (summary->bytes);
+ }
+ }
+
+ G_UNLOCK (cache);
+
+ return res;
+}
+
+static GBytes *
+flatpak_dir_cache_summary (FlatpakDir *self,
+ GBytes *bytes,
+ const char *name,
+ const char *url)
+{
+ CachedSummary *summary;
+ GBytes *res = NULL;
+
+ G_LOCK (cache);
+
+ /* This was already initialized in the cache-miss lookup */
+ g_assert (self->summary_cache != NULL);
+
+ summary = cached_summary_new (bytes, name, url);
+ g_hash_table_insert (self->summary_cache, summary->remote, summary);
+
+ G_UNLOCK (cache);
+
+ return res;
+}
+
static gboolean
flatpak_dir_remote_fetch_summary (FlatpakDir *self,
const char *name,
@@ -3657,13 +3747,34 @@ flatpak_dir_remote_fetch_summary (FlatpakDir *self,
GCancellable *cancellable,
GError **error)
{
- /* TODO: Add in-memory cache here */
+ g_autofree char *url = NULL;
+ gboolean is_local;
+
+ if (!ostree_repo_remote_get_url (self->repo, name, &url, error))
+ return NULL;
+
+ is_local = g_str_has_prefix (url, "file:");
+
+ /* No caching for local files */
+ if (!is_local)
+ {
+ GBytes *cached_summary = flatpak_dir_lookup_cached_summary (self, name, url);
+ if (cached_summary)
+ {
+ *out_summary = cached_summary;
+ return TRUE;
+ }
+ }
+
if (!ostree_repo_remote_fetch_summary (self->repo, name,
out_summary, NULL,
cancellable,
error))
return FALSE;
+ if (!is_local)
+ flatpak_dir_cache_summary (self, *out_summary, name, url);
+
return TRUE;
}