[gnome-builder/wip/libide] libide: perform cache regex lookup in worker thread
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: perform cache regex lookup in worker thread
- Date: Mon, 2 Mar 2015 03:38:19 +0000 (UTC)
commit 4d8dfdcbe8e828ec14e9058298d9b868f49b7433
Author: Christian Hergert <christian hergert me>
Date: Sun Mar 1 19:38:06 2015 -0800
libide: perform cache regex lookup in worker thread
libide/autotools/ide-makecache.c | 163 +++++++++++++++++++++++++++++++-------
1 files changed, 133 insertions(+), 30 deletions(-)
---
diff --git a/libide/autotools/ide-makecache.c b/libide/autotools/ide-makecache.c
index c0af52b..780de69 100644
--- a/libide/autotools/ide-makecache.c
+++ b/libide/autotools/ide-makecache.c
@@ -45,6 +45,7 @@ struct _IdeMakecache
GFile *parent;
GMappedFile *mapped;
GHashTable *file_targets_cache;
+ GHashTable *file_targets_neg_cache;
GHashTable *file_flags_cache;
};
@@ -642,6 +643,7 @@ ide_makecache_finalize (GObject *object)
g_clear_object (&self->makefile);
g_clear_pointer (&self->mapped, g_mapped_file_unref);
g_clear_pointer (&self->file_targets_cache, g_hash_table_unref);
+ g_clear_pointer (&self->file_targets_neg_cache, g_hash_table_unref);
g_clear_pointer (&self->file_flags_cache, g_hash_table_unref);
G_OBJECT_CLASS (ide_makecache_parent_class)->finalize (object);
@@ -709,6 +711,8 @@ ide_makecache_init (IdeMakecache *self)
{
self->file_targets_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify)g_strfreev);
+ self->file_targets_neg_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)g_strfreev);
self->file_flags_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify)g_strfreev);
}
@@ -755,77 +759,176 @@ ide_makecache_new_for_makefile_finish (GAsyncResult *result,
return g_task_propagate_pointer (task, error);
}
-const gchar * const *
-ide_makecache_get_file_targets (IdeMakecache *self,
- GFile *file)
+static void
+ide_makecache_get_file_targets_worker (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- g_autofree gchar *path = NULL;
+ IdeMakecache *self = source_object;
+ const gchar *path = task_data;
const gchar * const *ret;
- g_return_val_if_fail (IDE_IS_MAKECACHE (self), NULL);
- g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_assert (IDE_IS_MAKECACHE (self));
+ g_assert (G_IS_TASK (task));
+ g_assert (path);
- path = g_file_get_relative_path (self->parent, file);
- if (!path)
- return NULL;
+ ret = ide_makecache_get_file_targets_searched (self, path);
- ret = ide_makecache_get_file_targets_cached (self, path);
if (!ret)
- ret = ide_makecache_get_file_targets_searched (self, path);
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "target was not found in project");
+ return;
+ }
- return ret;
+ g_task_return_pointer (task, g_strdupv ((gchar **)ret), (GDestroyNotify)g_strfreev);
}
void
-ide_makecache_get_file_flags_async (IdeMakecache *self,
- GFile *file,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ide_makecache_get_file_targets_async (IdeMakecache *self,
+ GFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
g_autoptr(GTask) task = NULL;
- FileFlagsLookup *lookup;
- g_autofree gchar *path = NULL;
- g_autofree gchar *relative_path = NULL;
- const gchar * const *targets;
- gchar **argv;
+ const gchar * const *ret;
+ gchar *path = NULL;
g_return_if_fail (IDE_IS_MAKECACHE (self));
g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
- path = g_file_get_path (file);
- relative_path = g_file_get_relative_path (self->parent, file);
- targets = ide_makecache_get_file_targets (self, file);
+ path = g_file_get_relative_path (self->parent, file);
+ g_task_set_task_data (task, path, g_free);
- if (!targets)
+ if (!path)
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_INVALID_FILENAME,
- "No targets contain the file \"%s\"",
- path);
+ "File must be in the project path.");
+ return;
+ }
+
+ if (g_hash_table_contains (self->file_targets_neg_cache, path))
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "target could not be found");
+ return;
+ }
+
+ ret = ide_makecache_get_file_targets_cached (self, path);
+
+ if (ret)
+ {
+ g_task_return_pointer (task, g_strdupv ((gchar **)ret), (GDestroyNotify)g_strfreev);
+ return;
+ }
+
+ g_task_run_in_thread (task, ide_makecache_get_file_targets_worker);
+}
+
+gchar **
+ide_makecache_get_file_targets_finish (IdeMakecache *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+ gchar **ret;
+
+ g_return_val_if_fail (IDE_IS_MAKECACHE (self), NULL);
+ g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+ ret = g_task_propagate_pointer (task, error);
+
+ if (!ret)
+ {
+ const gchar *path;
+
+ path = g_task_get_task_data (task);
+ g_hash_table_insert (self->file_targets_neg_cache, g_strdup (path), NULL);
+ }
+
+ return ret;
+}
+
+static void
+ide_makecache__get_targets_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeMakecache *self = (IdeMakecache *)object;
+ g_autoptr(GTask) task = user_data;
+ gchar **targets;
+ GError *error = NULL;
+ GFile *file;
+ FileFlagsLookup *lookup;
+ g_autofree gchar *path = NULL;
+ g_autofree gchar *relative_path = NULL;
+ gchar **argv;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (IDE_IS_MAKECACHE (self));
+
+ targets = ide_makecache_get_file_targets_finish (self, result, &error);
+
+ if (!targets)
+ {
+ g_task_return_error (task, error);
return;
}
+ file = g_task_get_task_data (task);
+ path = g_file_get_path (file);
+ relative_path = g_file_get_relative_path (self->parent, file);
+
argv = g_hash_table_lookup (self->file_flags_cache, relative_path);
if (argv)
{
+ g_strfreev (targets);
g_task_return_pointer (task, argv, (GDestroyNotify)g_strfreev);
return;
}
lookup = g_new0 (FileFlagsLookup, 1);
- lookup->targets = g_strdupv ((gchar **)targets);
+ lookup->targets = targets;
lookup->relative_path = g_strdup (relative_path);
g_task_set_task_data (task, lookup, file_flags_lookup_free);
g_task_run_in_thread (task, ide_makecache_get_file_flags_worker);
}
+void
+ide_makecache_get_file_flags_async (IdeMakecache *self,
+ GFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+
+ g_return_if_fail (IDE_IS_MAKECACHE (self));
+ g_return_if_fail (G_IS_FILE (file));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+
+ ide_makecache_get_file_targets_async (self,
+ file,
+ g_task_get_cancellable (task),
+ ide_makecache__get_targets_cb,
+ g_object_ref (task));
+}
+
gchar **
ide_makecache_get_file_flags_finish (IdeMakecache *self,
GAsyncResult *result,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]