[nautilus] Rework the search directory model
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus] Rework the search directory model
- Date: Thu, 6 Sep 2012 19:23:58 +0000 (UTC)
commit 7d243639ae0b18aed67b73cbb4a531f5ad99ee4d
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Wed Sep 5 22:16:07 2012 -0400
Rework the search directory model
libnautilus-private/nautilus-search-engine-model.c | 314 +++++---------------
1 files changed, 75 insertions(+), 239 deletions(-)
---
diff --git a/libnautilus-private/nautilus-search-engine-model.c b/libnautilus-private/nautilus-search-engine-model.c
index 4c1144c..ad06396 100644
--- a/libnautilus-private/nautilus-search-engine-model.c
+++ b/libnautilus-private/nautilus-search-engine-model.c
@@ -33,31 +33,11 @@
#include <glib.h>
#include <gio/gio.h>
-#define BATCH_SIZE 500
-
-typedef struct {
- NautilusSearchEngineModel *engine;
- GCancellable *cancellable;
-
- GList *mime_types;
- char **words;
- GList *found_list;
-
- GQueue *directories; /* GFiles */
-
- GHashTable *visited;
-
- gint n_processed_files;
- GList *hits;
-} SearchData;
-
-
struct NautilusSearchEngineModelDetails {
NautilusQuery *query;
- SearchData *active_search;
-
- gboolean query_finished;
+ GList *hits;
+ NautilusDirectory *directory;
};
static void nautilus_search_provider_init (NautilusSearchProviderIface *iface);
@@ -75,276 +55,132 @@ finalize (GObject *object)
model = NAUTILUS_SEARCH_ENGINE_MODEL (object);
- if (model->details->query) {
- g_object_unref (model->details->query);
- model->details->query = NULL;
- }
-
- G_OBJECT_CLASS (nautilus_search_engine_model_parent_class)->finalize (object);
-}
-
-static SearchData *
-search_data_new (NautilusSearchEngineModel *engine,
- NautilusQuery *query)
-{
- SearchData *data;
- char *text, *lower, *normalized, *uri;
- GFile *location;
-
- data = g_new0 (SearchData, 1);
-
- data->engine = g_object_ref (engine);
- data->directories = g_queue_new ();
- data->visited = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- uri = nautilus_query_get_location (query);
- location = NULL;
- if (uri != NULL) {
- location = g_file_new_for_uri (uri);
- g_free (uri);
+ if (model->details->hits != NULL) {
+ g_list_free_full (model->details->hits, g_object_unref);
+ model->details->hits = NULL;
}
- if (location == NULL) {
- location = g_file_new_for_path ("/");
- }
- g_queue_push_tail (data->directories, location);
-
- text = nautilus_query_get_text (query);
- g_message ("text %s", text);
- normalized = g_utf8_normalize (text, -1, G_NORMALIZE_NFD);
- lower = g_utf8_strdown (normalized, -1);
- data->words = g_strsplit (lower, " ", -1);
- g_free (text);
- g_free (lower);
- g_free (normalized);
-
- data->mime_types = nautilus_query_get_mime_types (query);
-
- data->cancellable = g_cancellable_new ();
- return data;
-}
+ g_clear_object (&model->details->directory);
+ g_clear_object (&model->details->query);
-static void
-search_data_free (SearchData *data)
-{
- g_queue_foreach (data->directories,
- (GFunc)g_object_unref, NULL);
- g_queue_free (data->directories);
- g_hash_table_destroy (data->visited);
- g_object_unref (data->cancellable);
- g_strfreev (data->words);
- g_list_free_full (data->mime_types, g_free);
- g_list_free_full (data->hits, g_object_unref);
- g_object_unref (data->engine);
-
- g_free (data);
+ G_OBJECT_CLASS (nautilus_search_engine_model_parent_class)->finalize (object);
}
static gboolean
-search_done_idle (gpointer user_data)
+emit_finished_idle_cb (gpointer user_data)
{
- SearchData *data = user_data;
+ NautilusSearchEngineModel *model = user_data;
- if (!g_cancellable_is_cancelled (data->cancellable)) {
- nautilus_search_provider_finished (NAUTILUS_SEARCH_PROVIDER (data->engine));
- data->engine->details->active_search = NULL;
+ if (model->details->hits != NULL) {
+ nautilus_search_provider_hits_added (NAUTILUS_SEARCH_PROVIDER (model),
+ model->details->hits);
+ g_list_free_full (model->details->hits, g_object_unref);
+ model->details->hits = NULL;
}
- search_data_free (data);
-
- return FALSE;
-}
-
-typedef struct {
- GList *hits;
- SearchData *thread_data;
-} SearchHitsData;
-
-static gboolean
-search_add_hits_idle (gpointer user_data)
-{
- SearchHitsData *data = user_data;
-
- if (!g_cancellable_is_cancelled (data->thread_data->cancellable)) {
- nautilus_search_provider_hits_added (NAUTILUS_SEARCH_PROVIDER (data->thread_data->engine),
- data->hits);
- }
+ nautilus_search_provider_finished (NAUTILUS_SEARCH_PROVIDER (model));
- g_list_free_full (data->hits, g_object_unref);
- g_free (data);
+ g_clear_object (&model->details->directory);
+ g_object_unref (model);
return FALSE;
}
-static void
-send_batch (SearchData *thread_data)
+static gchar *
+prepare_query_pattern (NautilusSearchEngineModel *model)
{
- SearchHitsData *data;
+ gchar *text, *pattern, *normalized, *lower;
- thread_data->n_processed_files = 0;
+ text = nautilus_query_get_text (model->details->query);
+ normalized = g_utf8_normalize (text, -1, G_NORMALIZE_NFD);
+ lower = g_utf8_strdown (normalized, -1);
+ pattern = g_strdup_printf ("*%s*", lower);
- if (thread_data->hits) {
- data = g_new (SearchHitsData, 1);
- data->hits = thread_data->hits;
- data->thread_data = thread_data;
- g_idle_add (search_add_hits_idle, data);
- }
- thread_data->hits = NULL;
+ g_free (text);
+ g_free (normalized);
+ g_free (lower);
+
+ return pattern;
}
static void
-got_files_callback (NautilusDirectory *directory,
- GList *files,
- SearchData *data)
-{
- GList *node;
-
- for (node = files; node != NULL; node = node->next) {
- NautilusFile *file = node->data;
- char *display_name;
- char *normalized;
- char *lower_name;
- gboolean found;
- int i;
-
+model_directory_ready_cb (NautilusDirectory *directory,
+ GList *list,
+ gpointer user_data)
+{
+ NautilusSearchEngineModel *model = user_data;
+ gchar *uri, *pattern;
+ gchar *display_name, *lower;
+ GList *files, *l, *hits;
+ NautilusFile *file;
+
+ pattern = prepare_query_pattern (model);
+ files = nautilus_directory_get_file_list (directory);
+ hits = NULL;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
display_name = nautilus_file_get_display_name (file);
- g_message ("got %s", display_name);
- if (display_name == NULL) {
- continue;
- }
-
- normalized = g_utf8_normalize (display_name, -1, G_NORMALIZE_NFD);
- lower_name = g_utf8_strdown (normalized, -1);
- g_free (normalized);
-
- found = TRUE;
- for (i = 0; data->words[i] != NULL; i++) {
- if (strstr (lower_name, data->words[i]) == NULL) {
- found = FALSE;
- break;
- }
- }
- g_free (lower_name);
-
- if (found && data->mime_types) {
- GList *l;
-
- found = FALSE;
-
- for (l = data->mime_types; l != NULL; l = l->next) {
- if (nautilus_file_is_mime_type (file, l->data)) {
- found = TRUE;
- break;
- }
- }
- }
-
- if (found) {
- NautilusSearchHit *hit;
- GDateTime *dt;
- char *uri;
- time_t t;
+ lower = g_utf8_strdown (display_name, -1);
+ if (g_pattern_match_simple (pattern, lower)) {
uri = nautilus_file_get_uri (file);
- hit = nautilus_search_hit_new (uri);
- g_message ("FOUND %s", uri);
+ hits = g_list_prepend (hits, nautilus_search_hit_new (uri));
g_free (uri);
- nautilus_search_hit_set_fts_rank (hit, 10.0);
- t = nautilus_file_get_mtime (file);
- dt = g_date_time_new_from_unix_local (t);
- nautilus_search_hit_set_modification_time (hit, dt);
- g_date_time_unref (dt);
-
- data->hits = g_list_prepend (data->hits, hit);
- }
-
- data->n_processed_files++;
- if (data->n_processed_files > BATCH_SIZE) {
- send_batch (data);
}
- }
- send_batch (data);
- g_idle_add (search_done_idle, data);
-}
-
-static void
-visit_directory (GFile *dir, SearchData *data)
-{
- NautilusDirectory *directory;
- g_message ("searching %s", g_file_get_uri (dir));
- directory = nautilus_directory_get (dir);
- nautilus_directory_call_when_ready (directory,
- NAUTILUS_FILE_ATTRIBUTE_INFO,
- TRUE,
- (NautilusDirectoryCallback)got_files_callback,
- data);
- g_object_unref (directory);
-}
-
-static gpointer
-search_thread_func (gpointer user_data)
-{
- SearchData *data = user_data;
- GFile *dir;
- GFileInfo *info;
- const char *id;
-
- /* Insert id for toplevel directory into visited */
- dir = g_queue_peek_head (data->directories);
- info = g_file_query_info (dir, G_FILE_ATTRIBUTE_ID_FILE, 0, data->cancellable, NULL);
- if (info) {
- id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
- if (id) {
- g_hash_table_insert (data->visited, g_strdup (id), NULL);
- }
- g_object_unref (info);
+ g_free (lower);
+ g_free (display_name);
}
- while (!g_cancellable_is_cancelled (data->cancellable) &&
- (dir = g_queue_pop_head (data->directories)) != NULL) {
- visit_directory (dir, data);
- g_object_unref (dir);
- }
+ nautilus_file_list_free (files);
+ model->details->hits = hits;
- return NULL;
+ emit_finished_idle_cb (model);
}
static void
nautilus_search_engine_model_start (NautilusSearchProvider *provider)
{
NautilusSearchEngineModel *model;
- SearchData *data;
- GThread *thread;
+ GFile *location;
+ NautilusDirectory *directory;
+ gchar *uri;
model = NAUTILUS_SEARCH_ENGINE_MODEL (provider);
- if (model->details->active_search != NULL) {
+ if (model->details->query == NULL) {
return;
}
- if (model->details->query == NULL) {
+ g_object_ref (model);
+
+ uri = nautilus_query_get_location (model->details->query);
+ if (uri == NULL) {
+ g_idle_add (emit_finished_idle_cb, model);
return;
}
- data = search_data_new (model, model->details->query);
+ location = g_file_new_for_uri (uri);
+ directory = nautilus_directory_get_existing (location);
+ g_object_unref (location);
+ g_free (uri);
- thread = g_thread_new ("nautilus-search-model", search_thread_func, data);
- model->details->active_search = data;
+ if (directory == NULL) {
+ g_idle_add (emit_finished_idle_cb, model);
+ return;
+ }
- g_thread_unref (thread);
+ model->details->directory = directory;
+ nautilus_directory_call_when_ready (model->details->directory,
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
+ TRUE, model_directory_ready_cb, model);
}
static void
nautilus_search_engine_model_stop (NautilusSearchProvider *provider)
{
- NautilusSearchEngineModel *model;
-
- model = NAUTILUS_SEARCH_ENGINE_MODEL (provider);
-
- if (model->details->active_search != NULL) {
- g_cancellable_cancel (model->details->active_search->cancellable);
- model->details->active_search = NULL;
- }
+ /* do nothing */
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]