[gnome-builder/gnome-builder-3-28] util: backport find with depth
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-28] util: backport find with depth
- Date: Tue, 26 Jun 2018 03:47:11 +0000 (UTC)
commit cd7f2173631206fe749e0eacde7a4e1788f8732b
Author: Christian Hergert <chergert redhat com>
Date: Mon Jun 25 20:41:52 2018 -0700
util: backport find with depth
This will let us to make some code have less overhead on large projects.
src/libide/util/ide-glib.c | 85 +++++++++++++++++++++++++++++++++++++---------
src/libide/util/ide-glib.h | 7 ++++
2 files changed, 76 insertions(+), 16 deletions(-)
---
diff --git a/src/libide/util/ide-glib.c b/src/libide/util/ide-glib.c
index 92fb6638c..7bfc74eaf 100644
--- a/src/libide/util/ide-glib.c
+++ b/src/libide/util/ide-glib.c
@@ -18,6 +18,7 @@
#define G_LOG_DOMAIN "ide-glib"
+#include <dazzle.h>
#include <string.h>
#include "config.h"
@@ -410,11 +411,25 @@ ide_g_file_get_children_finish (GFile *file,
return IDE_PTR_ARRAY_STEAL_FULL (&ret);
}
+typedef struct
+{
+ GPatternSpec *spec;
+ guint depth;
+} Find;
+
+static void
+find_free (Find *f)
+{
+ dzl_clear_pointer (&f->spec, g_pattern_spec_free);
+ g_slice_free (Find, f);
+}
+
static void
populate_descendants_matching (GFile *file,
GCancellable *cancellable,
GPtrArray *results,
- GPatternSpec *spec)
+ GPatternSpec *spec,
+ guint depth)
{
g_autoptr(GFileEnumerator) enumerator = NULL;
g_autoptr(GPtrArray) children = NULL;
@@ -423,6 +438,9 @@ populate_descendants_matching (GFile *file,
g_assert (results != NULL);
g_assert (spec != NULL);
+ if (depth == 0)
+ return;
+
enumerator = g_file_enumerate_children (file,
G_FILE_ATTRIBUTE_STANDARD_NAME","
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","
@@ -467,7 +485,7 @@ populate_descendants_matching (GFile *file,
/* Don't recurse into known bad directories */
if (!ide_vcs_is_ignored (NULL, child, NULL))
- populate_descendants_matching (child, cancellable, results, spec);
+ populate_descendants_matching (child, cancellable, results, spec, depth - 1);
}
}
}
@@ -479,54 +497,66 @@ ide_g_file_find_worker (GTask *task,
GCancellable *cancellable)
{
GFile *file = source_object;
- GPatternSpec *spec = task_data;
+ Find *f = task_data;
g_autoptr(GPtrArray) ret = NULL;
g_assert (G_IS_TASK (task));
g_assert (G_IS_FILE (file));
- g_assert (spec != NULL);
+ g_assert (f != NULL);
+ g_assert (f->spec != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
ret = g_ptr_array_new_with_free_func (g_object_unref);
- populate_descendants_matching (file, cancellable, ret, spec);
+ populate_descendants_matching (file, cancellable, ret, f->spec, f->depth);
g_task_return_pointer (task, g_steal_pointer (&ret), (GDestroyNotify)g_ptr_array_unref);
}
/**
- * ide_g_file_find_async:
+ * ide_g_file_find_with_depth_async:
* @file: a #IdeGlib
* @pattern: the glob pattern to search for using GPatternSpec
+ * @max_depth: maximum tree depth to search
* @cancellable: (nullable): a #GCancellable or %NULL
* @callback: a callback to execute upon completion
* @user_data: closure data for @callback
*
* Searches descendants of @file for files matching @pattern.
*
+ * Only up to @max_depth subdirectories will be searched. However, if
+ * @max_depth is zero, then all directories will be searched.
+ *
* You may only match on the filename, not the directory.
*
- * Since: 3.28
+ * Since: 3.30
*/
void
-ide_g_file_find_async (GFile *file,
- const gchar *pattern,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ide_g_file_find_with_depth_async (GFile *file,
+ const gchar *pattern,
+ guint depth,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
g_autoptr(GTask) task = NULL;
- g_autoptr(GPatternSpec) spec = NULL;
+ Find *f;
g_return_if_fail (G_IS_FILE (file));
g_return_if_fail (pattern != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+ if (depth == 0)
+ depth = G_MAXUINT;
+
task = g_task_new (file, cancellable, callback, user_data);
g_task_set_source_tag (task, ide_g_file_find_async);
g_task_set_priority (task, G_PRIORITY_LOW + 100);
- spec = g_pattern_spec_new (pattern);
+ f = g_slice_new0 (Find);
+ f->spec = g_pattern_spec_new (pattern);
+ f->depth = depth;
+ g_task_set_task_data (task, f, (GDestroyNotify)find_free);
- if (spec == NULL)
+ if (f->spec == NULL)
{
g_task_return_new_error (task,
G_IO_ERROR,
@@ -536,10 +566,33 @@ ide_g_file_find_async (GFile *file,
return;
}
- g_task_set_task_data (task, g_steal_pointer (&spec), (GDestroyNotify)g_pattern_spec_free);
g_task_run_in_thread (task, ide_g_file_find_worker);
}
+/**
+ * ide_g_file_find_async:
+ * @file: a #IdeGlib
+ * @pattern: the glob pattern to search for using GPatternSpec
+ * @cancellable: (nullable): a #GCancellable or %NULL
+ * @callback: a callback to execute upon completion
+ * @user_data: closure data for @callback
+ *
+ * Searches descendants of @file for files matching @pattern.
+ *
+ * You may only match on the filename, not the directory.
+ *
+ * Since: 3.28
+ */
+void
+ide_g_file_find_async (GFile *file,
+ const gchar *pattern,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ide_g_file_find_with_depth_async (file, pattern, G_MAXUINT, cancellable, callback, user_data);
+}
+
/**
* ide_g_file_find_finish:
* @file: a #GFile
diff --git a/src/libide/util/ide-glib.h b/src/libide/util/ide-glib.h
index 147772037..ff8eeee01 100644
--- a/src/libide/util/ide-glib.h
+++ b/src/libide/util/ide-glib.h
@@ -60,6 +60,13 @@ IDE_AVAILABLE_IN_3_28
gchar *ide_g_file_get_uncanonical_relative_path (GFile *file,
GFile *other);
IDE_AVAILABLE_IN_3_28
+void ide_g_file_find_with_depth_async (GFile *file,
+ const gchar *pattern,
+ guint max_depth,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_3_28
void ide_g_file_find_async (GFile *file,
const gchar *pattern,
GCancellable *cancellable,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]