Commit ddded19a authored by António Fernandes's avatar António Fernandes 🐚 Committed by Ernestas Kulik

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.
parent 3feda782
Pipeline #45634 passed with stages
in 9 minutes and 21 seconds
...@@ -2238,20 +2238,21 @@ nautilus_mime_types_group_get_name (gint group_index) ...@@ -2238,20 +2238,21 @@ nautilus_mime_types_group_get_name (gint group_index)
return gettext (mimetype_groups[group_index].name); return gettext (mimetype_groups[group_index].name);
} }
GList * GPtrArray *
nautilus_mime_types_group_get_mimetypes (gint group_index) nautilus_mime_types_group_get_mimetypes (gint group_index)
{ {
GList *mimetypes; GStrv group;
gint i; GPtrArray *mimetypes;
g_return_val_if_fail (group_index < G_N_ELEMENTS (mimetype_groups), NULL); 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 */ /* 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; return mimetypes;
......
...@@ -51,4 +51,4 @@ void nautilus_mime_activate_file (GtkWi ...@@ -51,4 +51,4 @@ void nautilus_mime_activate_file (GtkWi
NautilusWindowOpenFlags flags); NautilusWindowOpenFlags flags);
gint nautilus_mime_types_get_number_of_groups (void); gint nautilus_mime_types_get_number_of_groups (void);
const gchar* nautilus_mime_types_group_get_name (gint group_index); const gchar* nautilus_mime_types_group_get_name (gint group_index);
GList* nautilus_mime_types_group_get_mimetypes (gint group_index); GPtrArray* nautilus_mime_types_group_get_mimetypes (gint group_index);
\ No newline at end of file
...@@ -445,7 +445,7 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover, ...@@ -445,7 +445,7 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover,
gpointer user_data) gpointer user_data)
{ {
NautilusQueryEditor *editor; NautilusQueryEditor *editor;
g_autoptr (GList) mimetypes = NULL; g_autoptr (GPtrArray) mimetypes = NULL;
editor = NAUTILUS_QUERY_EDITOR (user_data); editor = NAUTILUS_QUERY_EDITOR (user_data);
...@@ -473,7 +473,8 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover, ...@@ -473,7 +473,8 @@ search_popover_mime_type_changed_cb (NautilusSearchPopover *popover,
{ {
g_autofree gchar *display_name = NULL; 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); display_name = g_content_type_get_description (mimetype);
gd_tagged_entry_tag_set_label (editor->mime_types_tag, display_name); gd_tagged_entry_tag_set_label (editor->mime_types_tag, display_name);
gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry), gd_tagged_entry_add_tag (GD_TAGGED_ENTRY (editor->entry),
......
...@@ -38,7 +38,7 @@ struct _NautilusQuery ...@@ -38,7 +38,7 @@ struct _NautilusQuery
char *text; char *text;
GFile *location; GFile *location;
GList *mime_types; GPtrArray *mime_types;
gboolean show_hidden; gboolean show_hidden;
GPtrArray *date_range; GPtrArray *date_range;
NautilusQueryRecursive recursive; NautilusQueryRecursive recursive;
...@@ -249,9 +249,9 @@ nautilus_query_class_init (NautilusQueryClass *class) ...@@ -249,9 +249,9 @@ nautilus_query_class_init (NautilusQueryClass *class)
G_PARAM_READWRITE)); 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, g_object_class_install_property (gobject_class,
...@@ -337,8 +337,9 @@ nautilus_query_class_init (NautilusQueryClass *class) ...@@ -337,8 +337,9 @@ nautilus_query_class_init (NautilusQueryClass *class)
static void static void
nautilus_query_init (NautilusQuery *query) nautilus_query_init (NautilusQuery *query)
{ {
query->show_hidden = TRUE;
query->location = g_file_new_for_path (g_get_home_dir ()); 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_type = g_settings_get_enum (nautilus_preferences, "search-filter-time-type");
query->search_content = NAUTILUS_QUERY_SEARCH_CONTENT_SIMPLE; query->search_content = NAUTILUS_QUERY_SEARCH_CONTENT_SIMPLE;
g_mutex_init (&query->prepared_words_mutex); g_mutex_init (&query->prepared_words_mutex);
...@@ -464,22 +465,44 @@ nautilus_query_set_location (NautilusQuery *query, ...@@ -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) nautilus_query_get_mime_types (NautilusQuery *query)
{ {
g_return_val_if_fail (NAUTILUS_IS_QUERY (query), NULL); 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 void
nautilus_query_set_mime_types (NautilusQuery *query, 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 (NAUTILUS_IS_QUERY (query));
g_return_if_fail (mime_types != NULL);
g_list_free_full (query->mime_types, g_free); g_clear_pointer (&query->mime_types, g_ptr_array_unref);
query->mime_types = g_list_copy_deep (mime_types, (GCopyFunc) g_strdup, NULL); query->mime_types = g_ptr_array_ref (mime_types);
g_object_notify (G_OBJECT (query), "mimetypes"); g_object_notify (G_OBJECT (query), "mimetypes");
} }
...@@ -656,7 +679,7 @@ nautilus_query_is_empty (NautilusQuery *query) ...@@ -656,7 +679,7 @@ nautilus_query_is_empty (NautilusQuery *query)
if (!query->date_range && if (!query->date_range &&
(!query->text || (query->text && query->text[0] == '\0')) && (!query->text || (query->text && query->text[0] == '\0')) &&
!query->mime_types) query->mime_types->len == 0)
{ {
return TRUE; return TRUE;
} }
......
...@@ -57,8 +57,8 @@ GFile* nautilus_query_get_location (NautilusQuery *query); ...@@ -57,8 +57,8 @@ GFile* nautilus_query_get_location (NautilusQuery *query);
void nautilus_query_set_location (NautilusQuery *query, void nautilus_query_set_location (NautilusQuery *query,
GFile *location); GFile *location);
GList * nautilus_query_get_mime_types (NautilusQuery *query); GPtrArray * nautilus_query_get_mime_types (NautilusQuery *query);
void nautilus_query_set_mime_types (NautilusQuery *query, GList *mime_types); void nautilus_query_set_mime_types (NautilusQuery *query, GPtrArray *mime_types);
NautilusQuerySearchContent nautilus_query_get_search_content (NautilusQuery *query); NautilusQuerySearchContent nautilus_query_get_search_content (NautilusQuery *query);
void nautilus_query_set_search_content (NautilusQuery *query, void nautilus_query_set_search_content (NautilusQuery *query,
......
...@@ -130,8 +130,9 @@ model_directory_ready_cb (NautilusDirectory *directory, ...@@ -130,8 +130,9 @@ model_directory_ready_cb (NautilusDirectory *directory,
gpointer user_data) gpointer user_data)
{ {
NautilusSearchEngineModel *model = user_data; NautilusSearchEngineModel *model = user_data;
g_autoptr (GPtrArray) mime_types = NULL;
gchar *uri, *display_name; gchar *uri, *display_name;
GList *files, *hits, *mime_types, *l, *m; GList *files, *hits, *l;
NautilusFile *file; NautilusFile *file;
gdouble match; gdouble match;
gboolean found; gboolean found;
...@@ -152,13 +153,13 @@ model_directory_ready_cb (NautilusDirectory *directory, ...@@ -152,13 +153,13 @@ model_directory_ready_cb (NautilusDirectory *directory,
match = nautilus_query_matches_string (model->query, display_name); match = nautilus_query_matches_string (model->query, display_name);
found = (match > -1); found = (match > -1);
if (found && mime_types) if (found && mime_types->len > 0)
{ {
found = FALSE; 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; found = TRUE;
break; break;
...@@ -204,7 +205,6 @@ model_directory_ready_cb (NautilusDirectory *directory, ...@@ -204,7 +205,6 @@ model_directory_ready_cb (NautilusDirectory *directory,
g_free (display_name); g_free (display_name);
} }
g_list_free_full (mime_types, g_free);
nautilus_file_list_free (files); nautilus_file_list_free (files);
model->hits = hits; model->hits = hits;
......
...@@ -186,8 +186,8 @@ recent_thread_func (gpointer user_data) ...@@ -186,8 +186,8 @@ recent_thread_func (gpointer user_data)
g_autoptr (NautilusSearchEngineRecent) self = NAUTILUS_SEARCH_ENGINE_RECENT (user_data); g_autoptr (NautilusSearchEngineRecent) self = NAUTILUS_SEARCH_ENGINE_RECENT (user_data);
g_autoptr (GPtrArray) date_range = NULL; g_autoptr (GPtrArray) date_range = NULL;
g_autoptr (GFile) query_location = NULL; g_autoptr (GFile) query_location = NULL;
g_autoptr (GPtrArray) mime_types = NULL;
GList *recent_items; GList *recent_items;
GList *mime_types;
GList *hits; GList *hits;
GList *l; GList *l;
...@@ -258,16 +258,14 @@ recent_thread_func (gpointer user_data) ...@@ -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); const gchar *mime_type = gtk_recent_info_get_mime_type (info);
gboolean found = FALSE; gboolean found = FALSE;
for (ml = mime_types; mime_type != NULL && ml != NULL; for (gint i = 0; mime_type != NULL && i < mime_types->len; i++)
ml = ml->next)
{ {
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; found = TRUE;
break; break;
...@@ -318,7 +316,6 @@ recent_thread_func (gpointer user_data) ...@@ -318,7 +316,6 @@ recent_thread_func (gpointer user_data)
search_add_hits_idle (self, hits); search_add_hits_idle (self, hits);
g_list_free_full (recent_items, (GDestroyNotify) gtk_recent_info_unref); g_list_free_full (recent_items, (GDestroyNotify) gtk_recent_info_unref);
g_list_free_full (mime_types, g_free);
return NULL; return NULL;
} }
......
...@@ -47,7 +47,7 @@ typedef struct ...@@ -47,7 +47,7 @@ typedef struct
NautilusSearchEngineSimple *engine; NautilusSearchEngineSimple *engine;
GCancellable *cancellable; GCancellable *cancellable;
GList *mime_types; GPtrArray *mime_types;
GList *found_list; GList *found_list;
GQueue *directories; /* GFiles */ GQueue *directories; /* GFiles */
...@@ -119,7 +119,7 @@ search_thread_data_free (SearchThreadData *data) ...@@ -119,7 +119,7 @@ search_thread_data_free (SearchThreadData *data)
g_hash_table_destroy (data->visited); g_hash_table_destroy (data->visited);
g_object_unref (data->cancellable); g_object_unref (data->cancellable);
g_object_unref (data->query); 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_list_free_full (data->hits, g_object_unref);
g_object_unref (data->engine); g_object_unref (data->engine);
...@@ -216,7 +216,6 @@ visit_directory (GFile *dir, ...@@ -216,7 +216,6 @@ visit_directory (GFile *dir,
const char *mime_type, *display_name; const char *mime_type, *display_name;
gdouble match; gdouble match;
gboolean is_hidden, found; gboolean is_hidden, found;
GList *l;
const char *id; const char *id;
gboolean visited; gboolean visited;
guint64 atime; guint64 atime;
...@@ -226,7 +225,7 @@ visit_directory (GFile *dir, ...@@ -226,7 +225,7 @@ visit_directory (GFile *dir,
gchar *uri; gchar *uri;
enumerator = g_file_enumerate_children (dir, enumerator = g_file_enumerate_children (dir,
data->mime_types != NULL ? data->mime_types->len > 0 ?
STD_ATTRIBUTES "," STD_ATTRIBUTES ","
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
: :
...@@ -262,14 +261,14 @@ visit_directory (GFile *dir, ...@@ -262,14 +261,14 @@ visit_directory (GFile *dir,
match = nautilus_query_matches_string (data->query, display_name); match = nautilus_query_matches_string (data->query, display_name);
found = (match > -1); found = (match > -1);
if (found && data->mime_types) if (found && data->mime_types->len > 0)
{ {
mime_type = g_file_info_get_content_type (info); mime_type = g_file_info_get_content_type (info);
found = FALSE; 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; found = TRUE;
break; break;
......
...@@ -293,8 +293,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider) ...@@ -293,8 +293,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
gchar *query_text, *search_text, *location_uri, *downcase; gchar *query_text, *search_text, *location_uri, *downcase;
GFile *location; GFile *location;
GString *sparql; GString *sparql;
GList *mimetypes, *l; g_autoptr (GPtrArray) mimetypes = NULL;
gint mime_count;
GPtrArray *date_range; GPtrArray *date_range;
tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (provider); tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (provider);
...@@ -327,7 +326,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider) ...@@ -327,7 +326,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
location = nautilus_query_get_location (tracker->query); location = nautilus_query_get_location (tracker->query);
location_uri = location ? g_file_get_uri (location) : NULL; location_uri = location ? g_file_get_uri (location) : NULL;
mimetypes = nautilus_query_get_mime_types (tracker->query); 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)"); 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) ...@@ -349,7 +347,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
g_string_append_printf (sparql, "; fts:match '\"%s\"*'", search_text); 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"); g_string_append (sparql, "; nie:mimeType ?mime");
} }
...@@ -409,19 +407,19 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider) ...@@ -409,19 +407,19 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
g_ptr_array_unref (date_range); g_ptr_array_unref (date_range);
} }
if (mime_count > 0) if (mimetypes->len > 0)
{ {
g_string_append (sparql, " && ("); 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 (sparql, " || ");
} }
g_string_append_printf (sparql, "fn:contains(?mime, '%s')", g_string_append_printf (sparql, "fn:contains(?mime, '%s')",
(gchar *) l->data); (gchar *) g_ptr_array_index (mimetypes, i));
} }
g_string_append (sparql, ")\n"); g_string_append (sparql, ")\n");
} }
...@@ -438,7 +436,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider) ...@@ -438,7 +436,6 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
g_free (search_text); g_free (search_text);
g_free (location_uri); g_free (location_uri);
g_list_free_full (mimetypes, g_free);
g_object_unref (location); g_object_unref (location);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment