[nautilus] Rework the search directory model



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]