searchengine: Populate filesystem model in an idle
When starting a search over a very populated filesystem, it is possible that typing the first chars will return a too high number of results. Even though iterating through the cursor is in itself very fast, extracting the GIO information from those many files at once is not going to be as fast. In order to increase interactivity (i.e. not make things possibly sluggish) iterate the cursor in an idle function and add search results to the filechooser model little by little. If the user keeps typing (as it is likely will happen), there will be better chances to cancel and proceed to the next query timely. If not, the results will be there soon enough.
This commit is contained in:
		 Carlos Garnacho
					Carlos Garnacho
				
			
				
					committed by
					
						 Jan Alexander Steffens (heftig)
						Jan Alexander Steffens (heftig)
					
				
			
			
				
	
			
			
			 Jan Alexander Steffens (heftig)
						Jan Alexander Steffens (heftig)
					
				
			
						parent
						
							870ecf2b81
						
					
				
				
					commit
					f550bd6391
				
			| @ -34,6 +34,8 @@ | ||||
|  | ||||
| #include "gtksearchenginetracker3.h" | ||||
|  | ||||
| #define N_RESULT_BATCH_ITEMS 50 | ||||
|  | ||||
| #define MINER_FS_BUS_NAME "org.freedesktop.Tracker3.Miner.Files" | ||||
|  | ||||
| #define SEARCH_QUERY_BASE(__PATTERN__)                                 \ | ||||
| @ -65,6 +67,7 @@ struct _GtkSearchEngineTracker3 | ||||
|   TrackerSparqlStatement *search_location_query; | ||||
|   TrackerSparqlStatement *file_check_query; | ||||
|   GCancellable *cancellable; | ||||
|   guint idle_id; | ||||
|   GtkQuery *query; | ||||
|   gboolean query_pending; | ||||
| }; | ||||
| @ -74,6 +77,13 @@ struct _GtkSearchEngineTracker3Class | ||||
|   GtkSearchEngineClass parent_class; | ||||
| }; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   TrackerSparqlCursor *cursor; | ||||
|   GtkSearchEngineTracker3 *engine; | ||||
|   gboolean got_results; | ||||
| } CursorData; | ||||
|  | ||||
| static void gtk_search_engine_tracker3_initable_iface_init (GInitableIface *iface); | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (GtkSearchEngineTracker3, | ||||
| @ -97,6 +107,8 @@ finalize (GObject *object) | ||||
|       g_object_unref (engine->cancellable); | ||||
|     } | ||||
|  | ||||
|   g_clear_handle_id (&engine->idle_id, g_source_remove); | ||||
|  | ||||
|   g_clear_object (&engine->search_query); | ||||
|   g_clear_object (&engine->search_location_query); | ||||
|   g_clear_object (&engine->file_check_query); | ||||
| @ -149,6 +161,59 @@ create_file_info (TrackerSparqlCursor *cursor) | ||||
|   return info; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| handle_cursor_idle_cb (gpointer user_data) | ||||
| { | ||||
|   CursorData *data = user_data; | ||||
|   GtkSearchEngineTracker3 *engine = data->engine; | ||||
|   TrackerSparqlCursor *cursor = data->cursor; | ||||
|   gboolean has_next; | ||||
|   GList *hits = NULL; | ||||
|   GtkSearchHit *hit; | ||||
|   int i = 0; | ||||
|  | ||||
|   for (i = 0; i < N_RESULT_BATCH_ITEMS; i++) | ||||
|     { | ||||
|       const gchar *url; | ||||
|  | ||||
|       has_next = tracker_sparql_cursor_next (cursor, NULL, NULL); | ||||
|       if (!has_next) | ||||
|         break; | ||||
|  | ||||
|       url = tracker_sparql_cursor_get_string (cursor, 0, NULL); | ||||
|       hit = g_slice_new0 (GtkSearchHit); | ||||
|       hit->file = g_file_new_for_uri (url); | ||||
|       hit->info = create_file_info (cursor); | ||||
|       hits = g_list_prepend (hits, hit); | ||||
|       data->got_results = TRUE; | ||||
|     } | ||||
|  | ||||
|   _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits); | ||||
|  | ||||
|   g_list_free_full (hits, free_hit); | ||||
|  | ||||
|   if (has_next) | ||||
|     return G_SOURCE_CONTINUE; | ||||
|   else | ||||
|     { | ||||
|       engine->idle_id = 0; | ||||
|       return G_SOURCE_REMOVE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| cursor_data_free (gpointer user_data) | ||||
| { | ||||
|   CursorData *data = user_data; | ||||
|  | ||||
|   tracker_sparql_cursor_close (data->cursor); | ||||
|   _gtk_search_engine_finished (GTK_SEARCH_ENGINE (data->engine), | ||||
|                                data->got_results); | ||||
|   g_object_unref (data->cursor); | ||||
|   g_object_unref (data->engine); | ||||
|   g_free (data); | ||||
| } | ||||
|  | ||||
| static void | ||||
| query_callback (TrackerSparqlStatement *statement, | ||||
|                 GAsyncResult           *res, | ||||
| @ -156,9 +221,8 @@ query_callback (TrackerSparqlStatement *statement, | ||||
| { | ||||
|   GtkSearchEngineTracker3 *engine; | ||||
|   TrackerSparqlCursor *cursor; | ||||
|   GList *hits = NULL; | ||||
|   GError *error = NULL; | ||||
|   GtkSearchHit *hit; | ||||
|   CursorData *data; | ||||
|  | ||||
|   engine = GTK_SEARCH_ENGINE_TRACKER3 (user_data); | ||||
|  | ||||
| @ -174,25 +238,14 @@ query_callback (TrackerSparqlStatement *statement, | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   while (tracker_sparql_cursor_next (cursor, NULL, NULL)) | ||||
|     { | ||||
|       const gchar *url; | ||||
|   data = g_new0 (CursorData, 1); | ||||
|   data->cursor = cursor; | ||||
|   data->engine = engine; | ||||
|  | ||||
|       url = tracker_sparql_cursor_get_string (cursor, 0, NULL); | ||||
|       hit = g_slice_new0 (GtkSearchHit); | ||||
|       hit->file = g_file_new_for_uri (url); | ||||
|       hit->info = create_file_info (cursor); | ||||
|       hits = g_list_prepend (hits, hit); | ||||
|     } | ||||
|  | ||||
|   tracker_sparql_cursor_close (cursor); | ||||
|  | ||||
|   _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits); | ||||
|   _gtk_search_engine_finished (GTK_SEARCH_ENGINE (engine), hits != NULL); | ||||
|  | ||||
|   g_list_free_full (hits, free_hit); | ||||
|   g_object_unref (engine); | ||||
|   g_object_unref (cursor); | ||||
|   engine->idle_id = | ||||
|     g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, | ||||
|                      handle_cursor_idle_cb, | ||||
|                      data, cursor_data_free); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @ -271,6 +324,8 @@ gtk_search_engine_tracker3_stop (GtkSearchEngine *engine) | ||||
|       g_cancellable_cancel (tracker->cancellable); | ||||
|       tracker->query_pending = FALSE; | ||||
|     } | ||||
|  | ||||
|   g_clear_handle_id (&tracker->idle_id, g_source_remove); | ||||
| } | ||||
|  | ||||
| static void | ||||
|  | ||||
		Reference in New Issue
	
	Block a user