[nautilus/wip/antoniof/pointer-array-for-mime-type-filter: 4/4] query: Port MIME type filter to GPtrArray



commit ddded19a7852a5f002ceed561ac9e0310b69b637
Author: António Fernandes <antoniof gnome org>
Date:   Thu Nov 29 14:24:29 2018 +0000

    query: Port MIME type filter to GPtrArray
    
    We have been using doubly-linked lists to store MIME type names strings.
    
    But this is not a great container for strings, and we are copying the
    lists multiple times.
    
    So, use GPtrArray instead. This avoids copies thanks to reference
    counting, and enables autocleanup thanks to built-in data freeing.

 src/nautilus-mime-actions.c          | 13 ++++++-----
 src/nautilus-mime-actions.h          |  2 +-
 src/nautilus-query-editor.c          |  5 +++--
 src/nautilus-query.c                 | 43 +++++++++++++++++++++++++++---------
 src/nautilus-query.h                 |  4 ++--
 src/nautilus-search-engine-model.c   | 10 ++++-----
 src/nautilus-search-engine-recent.c  | 11 ++++-----
 src/nautilus-search-engine-simple.c  | 13 +++++------
 src/nautilus-search-engine-tracker.c | 15 +++++--------
 9 files changed, 67 insertions(+), 49 deletions(-)
---
diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
index e021d0b90..6f0ad9db5 100644
--- a/src/nautilus-mime-actions.c
+++ b/src/nautilus-mime-actions.c
@@ -2238,20 +2238,21 @@ nautilus_mime_types_group_get_name (gint group_index)
     return gettext (mimetype_groups[group_index].name);
 }
 
-GList *
+GPtrArray *
 nautilus_mime_types_group_get_mimetypes (gint group_index)
 {
-    GList *mimetypes;
-    gint i;
+    GStrv group;
+    GPtrArray *mimetypes;
 
     g_return_val_if_fail (group_index < G_N_ELEMENTS (mimetype_groups), NULL);
 
-    mimetypes = NULL;
+    group = mimetype_groups[group_index].mimetypes;
+    mimetypes = g_ptr_array_new_full (g_strv_length (group), g_free);
 
     /* Setup the new mimetypes set */
-    for (i = 0; mimetype_groups[group_index].mimetypes[i]; i++)
+    for (gint i = 0; group[i] != NULL; i++)
     {
-        mimetypes = g_list_append (mimetypes, mimetype_groups[group_index].mimetypes[i]);
+        g_ptr_array_add (mimetypes, g_strdup (group[i]));
     }
 
     return mimetypes;
diff --git a/src/nautilus-mime-actions.h b/src/nautilus-mime-actions.h
index 29be6b07c..9765894cb 100644
--- a/src/nautilus-mime-actions.h
+++ b/src/nautilus-mime-actions.h
@@ -51,4 +51,4 @@ void                   nautilus_mime_activate_file                        (GtkWi
                                                                           NautilusWindowOpenFlags  flags);
 gint                   nautilus_mime_types_get_number_of_groups           (void);
 const gchar*           nautilus_mime_types_group_get_name                 (gint                     
group_index);
-GList*                 nautilus_mime_types_group_get_mimetypes            (gint                     
group_index);
\ No newline at end of file
+GPtrArray*             nautilus_mime_types_group_get_mimetypes            (gint                     
group_index);
diff --git a/src/nautilus-query-editor.c b/src/nautilus-query-editor.c
index f4e380a1e..0f284b5b3 100644
--- a/src/nautilus-query-editor.c
+++ b/src/nautilus-query-editor.c
@@ -445,7 +445,7 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover,
                                      gpointer               user_data)
 {
     NautilusQueryEditor *editor;
-    g_autoptr (GList) mimetypes = NULL;
+    g_autoptr (GPtrArray) mimetypes = NULL;
 
     editor = NAUTILUS_QUERY_EDITOR (user_data);
 
@@ -473,7 +473,8 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover,
     {
         g_autofree gchar *display_name = NULL;
 
-        mimetypes = g_list_append (NULL, (gpointer) mimetype);
+        mimetypes = g_ptr_array_new_full (1, g_free);
+        g_ptr_array_add (mimetypes, g_strdup (mimetype));
         display_name = g_content_type_get_description (mimetype);
         gd_tagged_entry_tag_set_label (editor->mime_types_tag, display_name);
         gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry),
diff --git a/src/nautilus-query.c b/src/nautilus-query.c
index c1a01f142..9c43743fa 100644
--- a/src/nautilus-query.c
+++ b/src/nautilus-query.c
@@ -38,7 +38,7 @@ struct _NautilusQuery
 
     char *text;
     GFile *location;
-    GList *mime_types;
+    GPtrArray *mime_types;
     gboolean show_hidden;
     GPtrArray *date_range;
     NautilusQueryRecursive recursive;
@@ -249,9 +249,9 @@ nautilus_query_class_init (NautilusQueryClass *class)
                                                           G_PARAM_READWRITE));
 
     /**
-     * NautilusQuery::mimetypes:
+     * NautilusQuery::mimetypes: (type GPtrArray) (element-type gchar*)
      *
-     * MIME types the query holds.
+     * MIME types the query holds. An empty array means "Any type".
      *
      */
     g_object_class_install_property (gobject_class,
@@ -337,8 +337,9 @@ nautilus_query_class_init (NautilusQueryClass *class)
 static void
 nautilus_query_init (NautilusQuery *query)
 {
-    query->show_hidden = TRUE;
     query->location = g_file_new_for_path (g_get_home_dir ());
+    query->mime_types = g_ptr_array_new ();
+    query->show_hidden = TRUE;
     query->search_type = g_settings_get_enum (nautilus_preferences, "search-filter-time-type");
     query->search_content = NAUTILUS_QUERY_SEARCH_CONTENT_SIMPLE;
     g_mutex_init (&query->prepared_words_mutex);
@@ -464,22 +465,44 @@ nautilus_query_set_location (NautilusQuery *query,
     }
 }
 
-GList *
+/**
+ * nautilus_query_get_mime_type:
+ * @query: A #NautilusQuery
+ *
+ * Retrieves the current MIME Types filter from @query. Its content must not be
+ * modified. It can be read by multiple threads.
+ *
+ * Returns: (transfer container) A #GPtrArray reference with MIME type name strings.
+ */
+GPtrArray *
 nautilus_query_get_mime_types (NautilusQuery *query)
 {
     g_return_val_if_fail (NAUTILUS_IS_QUERY (query), NULL);
 
-    return g_list_copy_deep (query->mime_types, (GCopyFunc) g_strdup, NULL);
+    return g_ptr_array_ref (query->mime_types);
 }
 
+/**
+ * nautilus_query_set_mime_types:
+ * @query: A #NautilusQuery
+ * @mime_types: (transfer none): A #GPtrArray of MIME type strings
+ *
+ * Set a new MIME types filter for @query. Once set, the filter must not be
+ * modified, and it can only be replaced by setting another filter.
+ *
+ * Search engines that are already running for a previous filter will ignore the
+ * new filter. So, the caller must ensure that the search will be reloaded
+ * afterwards.
+ */
 void
 nautilus_query_set_mime_types (NautilusQuery *query,
-                               GList         *mime_types)
+                               GPtrArray     *mime_types)
 {
     g_return_if_fail (NAUTILUS_IS_QUERY (query));
+    g_return_if_fail (mime_types != NULL);
 
-    g_list_free_full (query->mime_types, g_free);
-    query->mime_types = g_list_copy_deep (mime_types, (GCopyFunc) g_strdup, NULL);
+    g_clear_pointer (&query->mime_types, g_ptr_array_unref);
+    query->mime_types = g_ptr_array_ref (mime_types);
 
     g_object_notify (G_OBJECT (query), "mimetypes");
 }
@@ -656,7 +679,7 @@ nautilus_query_is_empty (NautilusQuery *query)
 
     if (!query->date_range &&
         (!query->text || (query->text && query->text[0] == '\0')) &&
-        !query->mime_types)
+        query->mime_types->len == 0)
     {
         return TRUE;
     }
diff --git a/src/nautilus-query.h b/src/nautilus-query.h
index b600d3653..6d6f66250 100644
--- a/src/nautilus-query.h
+++ b/src/nautilus-query.h
@@ -57,8 +57,8 @@ GFile*         nautilus_query_get_location       (NautilusQuery *query);
 void           nautilus_query_set_location       (NautilusQuery *query,
                                                   GFile         *location);
 
-GList *        nautilus_query_get_mime_types     (NautilusQuery *query);
-void           nautilus_query_set_mime_types     (NautilusQuery *query, GList *mime_types);
+GPtrArray *    nautilus_query_get_mime_types     (NautilusQuery *query);
+void           nautilus_query_set_mime_types     (NautilusQuery *query, GPtrArray *mime_types);
 
 NautilusQuerySearchContent nautilus_query_get_search_content (NautilusQuery *query);
 void                       nautilus_query_set_search_content (NautilusQuery              *query,
diff --git a/src/nautilus-search-engine-model.c b/src/nautilus-search-engine-model.c
index c651d9507..509010e84 100644
--- a/src/nautilus-search-engine-model.c
+++ b/src/nautilus-search-engine-model.c
@@ -130,8 +130,9 @@ model_directory_ready_cb (NautilusDirectory *directory,
                           gpointer           user_data)
 {
     NautilusSearchEngineModel *model = user_data;
+    g_autoptr (GPtrArray) mime_types = NULL;
     gchar *uri, *display_name;
-    GList *files, *hits, *mime_types, *l, *m;
+    GList *files, *hits, *l;
     NautilusFile *file;
     gdouble match;
     gboolean found;
@@ -152,13 +153,13 @@ model_directory_ready_cb (NautilusDirectory *directory,
         match = nautilus_query_matches_string (model->query, display_name);
         found = (match > -1);
 
-        if (found && mime_types)
+        if (found && mime_types->len > 0)
         {
             found = FALSE;
 
-            for (m = mime_types; m != NULL; m = m->next)
+            for (gint i = 0; i < mime_types->len; i++)
             {
-                if (nautilus_file_is_mime_type (file, m->data))
+                if (nautilus_file_is_mime_type (file, g_ptr_array_index (mime_types, i)))
                 {
                     found = TRUE;
                     break;
@@ -204,7 +205,6 @@ model_directory_ready_cb (NautilusDirectory *directory,
         g_free (display_name);
     }
 
-    g_list_free_full (mime_types, g_free);
     nautilus_file_list_free (files);
     model->hits = hits;
 
diff --git a/src/nautilus-search-engine-recent.c b/src/nautilus-search-engine-recent.c
index 52bfff5ca..11a810608 100644
--- a/src/nautilus-search-engine-recent.c
+++ b/src/nautilus-search-engine-recent.c
@@ -186,8 +186,8 @@ recent_thread_func (gpointer user_data)
     g_autoptr (NautilusSearchEngineRecent) self = NAUTILUS_SEARCH_ENGINE_RECENT (user_data);
     g_autoptr (GPtrArray) date_range = NULL;
     g_autoptr (GFile) query_location = NULL;
+    g_autoptr (GPtrArray) mime_types = NULL;
     GList *recent_items;
-    GList *mime_types;
     GList *hits;
     GList *l;
 
@@ -258,16 +258,14 @@ recent_thread_func (gpointer user_data)
                 }
             }
 
-            if (mime_types)
+            if (mime_types->len > 0)
             {
-                GList *ml;
                 const gchar *mime_type = gtk_recent_info_get_mime_type (info);
                 gboolean found = FALSE;
 
-                for (ml = mime_types; mime_type != NULL && ml != NULL;
-                     ml = ml->next)
+                for (gint i = 0; mime_type != NULL && i < mime_types->len; i++)
                 {
-                    if (g_content_type_is_a (mime_type, ml->data))
+                    if (g_content_type_is_a (mime_type, g_ptr_array_index (mime_types, i)))
                     {
                         found = TRUE;
                         break;
@@ -318,7 +316,6 @@ recent_thread_func (gpointer user_data)
     search_add_hits_idle (self, hits);
 
     g_list_free_full (recent_items, (GDestroyNotify) gtk_recent_info_unref);
-    g_list_free_full (mime_types, g_free);
 
     return NULL;
 }
diff --git a/src/nautilus-search-engine-simple.c b/src/nautilus-search-engine-simple.c
index 32ac41734..8def0a644 100644
--- a/src/nautilus-search-engine-simple.c
+++ b/src/nautilus-search-engine-simple.c
@@ -47,7 +47,7 @@ typedef struct
     NautilusSearchEngineSimple *engine;
     GCancellable *cancellable;
 
-    GList *mime_types;
+    GPtrArray *mime_types;
     GList *found_list;
 
     GQueue *directories;     /* GFiles */
@@ -119,7 +119,7 @@ search_thread_data_free (SearchThreadData *data)
     g_hash_table_destroy (data->visited);
     g_object_unref (data->cancellable);
     g_object_unref (data->query);
-    g_list_free_full (data->mime_types, g_free);
+    g_clear_pointer (&data->mime_types, g_ptr_array_unref);
     g_list_free_full (data->hits, g_object_unref);
     g_object_unref (data->engine);
 
@@ -216,7 +216,6 @@ visit_directory (GFile            *dir,
     const char *mime_type, *display_name;
     gdouble match;
     gboolean is_hidden, found;
-    GList *l;
     const char *id;
     gboolean visited;
     guint64 atime;
@@ -226,7 +225,7 @@ visit_directory (GFile            *dir,
     gchar *uri;
 
     enumerator = g_file_enumerate_children (dir,
-                                            data->mime_types != NULL ?
+                                            data->mime_types->len > 0 ?
                                             STD_ATTRIBUTES ","
                                             G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
                                             :
@@ -262,14 +261,14 @@ visit_directory (GFile            *dir,
         match = nautilus_query_matches_string (data->query, display_name);
         found = (match > -1);
 
-        if (found && data->mime_types)
+        if (found && data->mime_types->len > 0)
         {
             mime_type = g_file_info_get_content_type (info);
             found = FALSE;
 
-            for (l = data->mime_types; mime_type != NULL && l != NULL; l = l->next)
+            for (gint i = 0; i < data->mime_types->len; i++)
             {
-                if (g_content_type_is_a (mime_type, l->data))
+                if (g_content_type_is_a (mime_type, g_ptr_array_index (data->mime_types, i)))
                 {
                     found = TRUE;
                     break;
diff --git a/src/nautilus-search-engine-tracker.c b/src/nautilus-search-engine-tracker.c
index 267fb06b7..66494cae8 100644
--- a/src/nautilus-search-engine-tracker.c
+++ b/src/nautilus-search-engine-tracker.c
@@ -293,8 +293,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
     gchar *query_text, *search_text, *location_uri, *downcase;
     GFile *location;
     GString *sparql;
-    GList *mimetypes, *l;
-    gint mime_count;
+    g_autoptr (GPtrArray) mimetypes = NULL;
     GPtrArray *date_range;
 
     tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (provider);
@@ -327,7 +326,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
     location = nautilus_query_get_location (tracker->query);
     location_uri = location ? g_file_get_uri (location) : NULL;
     mimetypes = nautilus_query_get_mime_types (tracker->query);
-    mime_count = g_list_length (mimetypes);
 
     sparql = g_string_new ("SELECT DISTINCT nie:url(?urn) fts:rank(?urn) nfo:fileLastModified(?urn) 
nfo:fileLastAccessed(?urn)");
 
@@ -349,7 +347,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
         g_string_append_printf (sparql, "; fts:match '\"%s\"*'", search_text);
     }
 
-    if (mime_count > 0)
+    if (mimetypes->len > 0)
     {
         g_string_append (sparql, "; nie:mimeType ?mime");
     }
@@ -409,19 +407,19 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
         g_ptr_array_unref (date_range);
     }
 
-    if (mime_count > 0)
+    if (mimetypes->len > 0)
     {
         g_string_append (sparql, " && (");
 
-        for (l = mimetypes; l != NULL; l = l->next)
+        for (gint i = 0; i < mimetypes->len; i++)
         {
-            if (l != mimetypes)
+            if (i != 0)
             {
                 g_string_append (sparql, " || ");
             }
 
             g_string_append_printf (sparql, "fn:contains(?mime, '%s')",
-                                    (gchar *) l->data);
+                                    (gchar *) g_ptr_array_index (mimetypes, i));
         }
         g_string_append (sparql, ")\n");
     }
@@ -438,7 +436,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
 
     g_free (search_text);
     g_free (location_uri);
-    g_list_free_full (mimetypes, g_free);
     g_object_unref (location);
 }
 


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