[nautilus/gnome-3-6] query: move string matching code in NautilusQuery



commit bbe59c4bb7c1d389442d00e93a7ba8482b0e102e
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sun Oct 14 13:33:01 2012 -0400

    query: move string matching code in NautilusQuery
    
    This also allows us to use a heuristic to evaluate how good the filename
    match is.

 libnautilus-private/nautilus-query.c               |   59 ++++++++++++++++++++
 libnautilus-private/nautilus-query.h               |    2 +
 libnautilus-private/nautilus-search-engine-model.c |   30 +++-------
 .../nautilus-search-engine-simple.c                |   51 +++++------------
 libnautilus-private/nautilus-ui-utilities.c        |   12 ----
 libnautilus-private/nautilus-ui-utilities.h        |    2 -
 src/nautilus-shell-search-provider.c               |   30 +++-------
 7 files changed, 93 insertions(+), 93 deletions(-)
---
diff --git a/libnautilus-private/nautilus-query.c b/libnautilus-private/nautilus-query.c
index 2b78213..107adbd 100644
--- a/libnautilus-private/nautilus-query.c
+++ b/libnautilus-private/nautilus-query.c
@@ -35,6 +35,8 @@ struct NautilusQueryDetails {
 	char *location_uri;
 	GList *mime_types;
 	gboolean show_hidden;
+
+	char **prepared_words;
 };
 
 static void  nautilus_query_class_init       (NautilusQueryClass *class);
@@ -49,6 +51,7 @@ finalize (GObject *object)
 
 	query = NAUTILUS_QUERY (object);
 	g_free (query->details->text);
+	g_strfreev (query->details->prepared_words);
 	g_free (query->details->location_uri);
 
 	G_OBJECT_CLASS (nautilus_query_parent_class)->finalize (object);
@@ -73,6 +76,59 @@ nautilus_query_init (NautilusQuery *query)
 	query->details->show_hidden = TRUE;
 }
 
+static gchar *
+prepare_string_for_compare (const gchar *string)
+{
+	gchar *normalized, *res;
+
+	normalized = g_utf8_normalize (string, -1, G_NORMALIZE_NFD);
+	res = g_utf8_strdown (normalized, -1);
+	g_free (normalized);
+
+	return res;
+}
+
+gdouble
+nautilus_query_matches_string (NautilusQuery *query,
+			       const gchar *string)
+{
+	gchar *prepared_string, *ptr;
+	gboolean found;
+	gdouble retval;
+	gint idx;
+
+	if (!query->details->text) {
+		return -1;
+	}
+
+	if (!query->details->prepared_words) {
+		prepared_string = prepare_string_for_compare (query->details->text);
+		query->details->prepared_words = g_strsplit (prepared_string, " ", -1);
+		g_free (prepared_string);
+	}
+
+	prepared_string = prepare_string_for_compare (string);
+	found = TRUE;
+	ptr = NULL;
+
+	for (idx = 0; query->details->prepared_words[idx] != NULL; idx++) {
+		if ((ptr = strstr (prepared_string, query->details->prepared_words[idx])) == NULL) {
+			found = FALSE;
+			break;
+		}
+	}
+
+	if (!found) {
+		g_free (prepared_string);
+		return -1;
+	}
+
+	retval = MAX (10.0, (50.0 / idx) - (gdouble) (ptr - prepared_string));
+	g_free (prepared_string);
+
+	return retval;
+}
+
 NautilusQuery *
 nautilus_query_new (void)
 {
@@ -91,6 +147,9 @@ nautilus_query_set_text (NautilusQuery *query, const char *text)
 {
 	g_free (query->details->text);
 	query->details->text = g_strstrip (g_strdup (text));
+
+	g_strfreev (query->details->prepared_words);
+	query->details->prepared_words = NULL;
 }
 
 char *
diff --git a/libnautilus-private/nautilus-query.h b/libnautilus-private/nautilus-query.h
index 4c2e52b..f482700 100644
--- a/libnautilus-private/nautilus-query.h
+++ b/libnautilus-private/nautilus-query.h
@@ -61,6 +61,8 @@ GList *        nautilus_query_get_mime_types     (NautilusQuery *query);
 void           nautilus_query_set_mime_types     (NautilusQuery *query, GList *mime_types);
 void           nautilus_query_add_mime_type      (NautilusQuery *query, const char *mime_type);
 
+gdouble        nautilus_query_matches_string     (NautilusQuery *query, const gchar *string);
+
 char *         nautilus_query_to_readable_string (NautilusQuery *query);
 NautilusQuery *nautilus_query_load               (char *file);
 gboolean       nautilus_query_save               (NautilusQuery *query, char *file);
diff --git a/libnautilus-private/nautilus-search-engine-model.c b/libnautilus-private/nautilus-search-engine-model.c
index dadfe3a..3a57f2b 100644
--- a/libnautilus-private/nautilus-search-engine-model.c
+++ b/libnautilus-private/nautilus-search-engine-model.c
@@ -88,48 +88,34 @@ emit_finished_idle_cb (gpointer user_data)
 	return FALSE;
 }
 
-static gchar *
-prepare_pattern_for_comparison (NautilusSearchEngineModel *model)
-{
-	gchar *text, *prepared, *pattern;
-
-	text = nautilus_query_get_text (model->details->query);
-	prepared = nautilus_search_prepare_string_for_compare (text);
-	pattern = g_strdup_printf ("*%s*", prepared);
-
-	g_free (prepared);
-	g_free (text);
-
-	return pattern;
-}
-
 static void
 model_directory_ready_cb (NautilusDirectory	*directory,
 			  GList			*list,
 			  gpointer		 user_data)
 {
 	NautilusSearchEngineModel *model = user_data;
-	gchar *uri, *pattern;
-	gchar *display_name, *prepared;
+	gchar *uri, *display_name;
 	GList *files, *l, *hits;
 	NautilusFile *file;
+	gdouble match;
+	NautilusSearchHit *hit;
 
-	pattern = prepare_pattern_for_comparison (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);
-		prepared = nautilus_search_prepare_string_for_compare (display_name);
+		match = nautilus_query_matches_string (model->details->query, display_name);
 
-		if (g_pattern_match_simple (pattern, prepared)) {
+		if (match > -1) {
 			uri = nautilus_file_get_uri (file);
-			hits = g_list_prepend (hits, nautilus_search_hit_new (uri));
+			hit = nautilus_search_hit_new (uri);
+			nautilus_search_hit_set_fts_rank (hit, match);
+			hits = g_list_prepend (hits, hit);
 			g_free (uri);
 		}
 
-		g_free (prepared);
 		g_free (display_name);
 	}
 
diff --git a/libnautilus-private/nautilus-search-engine-simple.c b/libnautilus-private/nautilus-search-engine-simple.c
index bdcaf3d..4e7a8f7 100644
--- a/libnautilus-private/nautilus-search-engine-simple.c
+++ b/libnautilus-private/nautilus-search-engine-simple.c
@@ -43,7 +43,6 @@ typedef struct {
 	GCancellable *cancellable;
 
 	GList *mime_types;
-	char **words;
 	GList *found_list;
 
 	GQueue *directories; /* GFiles */
@@ -53,6 +52,8 @@ typedef struct {
 	gboolean recursive;
 	gint n_processed_files;
 	GList *hits;
+
+	NautilusQuery *query;
 } SearchThreadData;
 
 
@@ -91,7 +92,7 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
 			NautilusQuery *query)
 {
 	SearchThreadData *data;
-	char *text, *prepared, *uri;
+	char *uri;
 	GFile *location;
 	
 	data = g_new0 (SearchThreadData, 1);
@@ -99,23 +100,13 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
 	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);
+	data->query = g_object_ref (query);
+
 	uri = nautilus_query_get_location (query);
-	location = NULL;
-	if (uri != NULL) {
-		location = g_file_new_for_uri (uri);
-		g_free (uri);
-	}
-	if (location == NULL) {
-		location = g_file_new_for_path ("/");
-	}
-	g_queue_push_tail (data->directories, location);
-	
-	text = nautilus_query_get_text (query);
-	prepared = nautilus_search_prepare_string_for_compare (text);
-	data->words = g_strsplit (prepared, " ", -1);
-	g_free (text);
-	g_free (prepared);
+	location = g_file_new_for_uri (uri);
+	g_free (uri);
 
+	g_queue_push_tail (data->directories, location);
 	data->mime_types = nautilus_query_get_mime_types (query);
 
 	data->cancellable = g_cancellable_new ();
@@ -131,7 +122,7 @@ search_thread_data_free (SearchThreadData *data)
 	g_queue_free (data->directories);
 	g_hash_table_destroy (data->visited);
 	g_object_unref (data->cancellable);
-	g_strfreev (data->words);	
+	g_object_unref (data->query);
 	g_list_free_full (data->mime_types, g_free);
 	g_list_free_full (data->hits, g_object_unref);
 	g_object_unref (data->engine);
@@ -205,9 +196,8 @@ visit_directory (GFile *dir, SearchThreadData *data)
 	GFileInfo *info;
 	GFile *child;
 	const char *mime_type, *display_name;
-	char *prepared;
-	gboolean found, is_hidden;
-	int i;
+	gdouble match;
+	gboolean is_hidden, found;
 	GList *l;
 	const char *id;
 	gboolean visited;
@@ -232,21 +222,14 @@ visit_directory (GFile *dir, SearchThreadData *data)
 		}
 
 		is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
-		if (is_hidden && !nautilus_query_get_show_hidden_files (data->engine->details->query)) {
+		if (is_hidden && !nautilus_query_get_show_hidden_files (data->query)) {
 			goto next;
 		}
 
-		prepared = nautilus_search_prepare_string_for_compare (display_name);
+		child = g_file_get_child (dir, g_file_info_get_name (info));
+		match = nautilus_query_matches_string (data->query, display_name);
+		found = (match > -1);
 
-		found = TRUE;
-		for (i = 0; data->words[i] != NULL; i++) {
-			if (strstr (prepared, data->words[i]) == NULL) {
-				found = FALSE;
-				break;
-			}
-		}
-		g_free (prepared);
-		
 		if (found && data->mime_types) {
 			mime_type = g_file_info_get_content_type (info);
 			found = FALSE;
@@ -259,8 +242,6 @@ visit_directory (GFile *dir, SearchThreadData *data)
 			}
 		}
 		
-		child = g_file_get_child (dir, g_file_info_get_name (info));
-		
 		if (found) {
 			NautilusSearchHit *hit;
 			GTimeVal tv;
@@ -270,7 +251,7 @@ visit_directory (GFile *dir, SearchThreadData *data)
 			uri = g_file_get_uri (child);
 			hit = nautilus_search_hit_new (uri);
 			g_free (uri);
-			nautilus_search_hit_set_fts_rank (hit, 10.0);
+			nautilus_search_hit_set_fts_rank (hit, match);
 			g_file_info_get_modification_time (info, &tv);
 			dt = g_date_time_new_from_timeval_local (&tv);
 			nautilus_search_hit_set_modification_time (hit, dt);
diff --git a/libnautilus-private/nautilus-ui-utilities.c b/libnautilus-private/nautilus-ui-utilities.c
index b70a01f..539ddca 100644
--- a/libnautilus-private/nautilus-ui-utilities.c
+++ b/libnautilus-private/nautilus-ui-utilities.c
@@ -61,18 +61,6 @@ nautilus_ui_prepare_merge_ui (GtkUIManager *ui_manager,
 	g_object_unref (*action_group); /* owned by ui manager */
 }
 
-gchar *
-nautilus_search_prepare_string_for_compare (const gchar *string)
-{
-	gchar *normalized, *res;
-
-	normalized = g_utf8_normalize (string, -1, G_NORMALIZE_NFD);
-	res = g_utf8_strdown (normalized, -1);
-	g_free (normalized);
-
-	return res;
-}
-
 static void
 extension_action_callback (GtkAction *action,
 			   gpointer callback_data)
diff --git a/libnautilus-private/nautilus-ui-utilities.h b/libnautilus-private/nautilus-ui-utilities.h
index 9020a12..12e2e5e 100644
--- a/libnautilus-private/nautilus-ui-utilities.h
+++ b/libnautilus-private/nautilus-ui-utilities.h
@@ -36,8 +36,6 @@ void        nautilus_ui_prepare_merge_ui           (GtkUIManager      *ui_manage
 						    GtkActionGroup   **action_group);
 GtkAction * nautilus_action_from_menu_item         (NautilusMenuItem  *item);
 
-gchar * nautilus_search_prepare_string_for_compare (const gchar *string);
-
 GdkPixbuf * nautilus_ui_get_menu_icon              (const char        *icon_name);
 
 char * nautilus_escape_action_name                 (const char        *action_name,
diff --git a/src/nautilus-shell-search-provider.c b/src/nautilus-shell-search-provider.c
index 649ea15..fc0c655 100644
--- a/src/nautilus-shell-search-provider.c
+++ b/src/nautilus-shell-search-provider.c
@@ -298,7 +298,7 @@ search_hit_candidate_new (const gchar *uri,
   SearchHitCandidate *candidate = g_slice_new0 (SearchHitCandidate);
 
   candidate->uri = g_strdup (uri);
-  candidate->string_for_compare = nautilus_search_prepare_string_for_compare (name);
+  candidate->string_for_compare = g_strdup (name);
 
   return candidate;
 }
@@ -309,10 +309,9 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
   NautilusSearchHit *hit;
   NautilusBookmark *bookmark;
   const gchar *name;
-  gint length, idx, j;
-  gchar *query_text, *string, *uri;
-  gchar **terms;
-  gboolean found;
+  gint length, idx;
+  gchar *string, *uri;
+  gdouble match;
   GList *l, *m, *drives, *volumes, *mounts, *mounts_to_check, *candidates;
   GDrive *drive;
   GVolume *volume;
@@ -321,12 +320,6 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
   SearchHitCandidate *candidate;
 
   candidates = NULL;
-  query_text = nautilus_query_get_text (self->current_search->query);
-  string = nautilus_search_prepare_string_for_compare (query_text);
-  terms = g_strsplit (string, " ", -1);
-
-  g_free (string);
-  g_free (query_text);
 
   /* first add bookmarks */
   length = nautilus_bookmark_list_length (self->bookmarks);
@@ -430,24 +423,17 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
 
   for (l = candidates; l != NULL; l = l->next) {
     candidate = l->data;
-    found = TRUE;
+    match = nautilus_query_matches_string (self->current_search->query,
+                                           candidate->string_for_compare);
 
-    for (j = 0; terms[j] != NULL; j++) {
-      if (strstr (candidate->string_for_compare, terms[j]) == NULL) {
-        found = FALSE;
-        break;
-      }
-    }
-
-    if (found) {
+    if (match > -1) {
       hit = nautilus_search_hit_new (candidate->uri);
+      nautilus_search_hit_set_fts_rank (hit, match);
       nautilus_search_hit_compute_scores (hit, self->current_search->query);
       g_hash_table_replace (self->current_search->hits, g_strdup (candidate->uri), hit);
     }
   }
   g_list_free_full (candidates, (GDestroyNotify) search_hit_candidate_free);
-
-  g_strfreev (terms);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]