[gnome-logs] journalmodel: load entries in batches



commit 666d20774aa1c5b91ddf766bb2fe387a36bd8b59
Author: Lars Uebernickel <lars uebernic de>
Date:   Thu Feb 19 11:15:17 2015 +0100

    journalmodel: load entries in batches
    
    A major use case of gnome-logs is to open it to quickly see the most
    recent log entries. It doesn't make sense to read all available entries
    from disk and create row widgets for each of them.
    
    Thus, make GlJournalModel only load the first 50 entries and trigger it
    to load more once the user scrolls the listbox to the bottom.
    
    We still have to load all entries once a search is started.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728317

 src/gl-eventviewlist.c |   18 ++++++++++++++
 src/gl-journal-model.c |   60 ++++++++++++++++++++++++++++++++++++++++++-----
 src/gl-journal-model.h |    3 ++
 3 files changed, 74 insertions(+), 7 deletions(-)
---
diff --git a/src/gl-eventviewlist.c b/src/gl-eventviewlist.c
index 53b6b78..753a7d0 100644
--- a/src/gl-eventviewlist.c
+++ b/src/gl-eventviewlist.c
@@ -542,6 +542,18 @@ on_search_bar_notify_search_mode_enabled (GtkSearchBar *search_bar,
 }
 
 static void
+gl_event_list_view_edge_reached (GtkScrolledWindow *scrolled,
+                                 GtkPositionType    pos,
+                                 gpointer           user_data)
+{
+    GlEventViewList *view = user_data;
+    GlEventViewListPrivate *priv = gl_event_view_list_get_instance_private (view);
+
+    if (pos == GTK_POS_BOTTOM)
+        gl_journal_model_fetch_more_entries (priv->journal_model, FALSE);
+}
+
+static void
 gl_event_view_list_finalize (GObject *object)
 {
     GlEventViewList *view = GL_EVENT_VIEW_LIST (object);
@@ -594,6 +606,9 @@ gl_event_view_list_init (GlEventViewList *view)
     priv->journal_model = gl_journal_model_new ();
     g_application_bind_busy_property (g_application_get_default (), priv->journal_model, "loading");
 
+    g_signal_connect (priv->event_scrolled, "edge-reached",
+                      G_CALLBACK (gl_event_list_view_edge_reached), view);
+
     gtk_list_box_bind_model (GTK_LIST_BOX (priv->entries_box),
                              G_LIST_MODEL (priv->journal_model),
                              gl_event_list_view_create_row_widget,
@@ -629,6 +644,9 @@ gl_event_view_list_search (GlEventViewList *view,
     g_free (priv->search_text);
     priv->search_text = g_strdup (needle);
 
+    /* for search, we need all entries - tell the model to fetch them */
+    gl_journal_model_fetch_more_entries (priv->journal_model, TRUE);
+
     gtk_list_box_invalidate_filter (priv->entries_box);
 }
 
diff --git a/src/gl-journal-model.c b/src/gl-journal-model.c
index ef078a5..8c9a9dd 100644
--- a/src/gl-journal-model.c
+++ b/src/gl-journal-model.c
@@ -6,9 +6,13 @@ struct _GlJournalModel
 {
     GObject parent_instance;
 
+    guint batch_size;
+
     GlJournal *journal;
     GPtrArray *entries;
 
+    guint n_entries_to_fetch;
+    gboolean fetched_all;
     guint idle_source;
 };
 
@@ -28,19 +32,29 @@ enum
 static GParamSpec *properties[N_PROPERTIES];
 
 static gboolean
-gl_journal_model_fetch_entries (gpointer user_data)
+gl_journal_model_fetch_idle (gpointer user_data)
 {
     GlJournalModel *model = user_data;
     GlJournalEntry *entry;
     guint last;
 
-    last = model->entries->len;
+    g_assert (model->n_entries_to_fetch > 0);
 
-    entry = gl_journal_previous (model->journal);
-    if (entry)
+    last = model->entries->len;
+    if ((entry = gl_journal_previous (model->journal)))
     {
+        model->n_entries_to_fetch--;
         g_ptr_array_add (model->entries, entry);
         g_list_model_items_changed (G_LIST_MODEL (model), last, 0, 1);
+    }
+    else
+    {
+        model->fetched_all = TRUE;
+        model->n_entries_to_fetch = 0;
+    }
+
+    if (model->n_entries_to_fetch > 0)
+    {
         return G_SOURCE_CONTINUE;
     }
     else
@@ -54,9 +68,11 @@ gl_journal_model_fetch_entries (gpointer user_data)
 static void
 gl_journal_model_init (GlJournalModel *model)
 {
+    model->batch_size = 50;
     model->journal = gl_journal_new ();
     model->entries = g_ptr_array_new_with_free_func (g_object_unref);
-    model->idle_source = g_idle_add_full (G_PRIORITY_LOW, gl_journal_model_fetch_entries, model, NULL);
+
+    gl_journal_model_fetch_more_entries (model, FALSE);
 }
 
 static void
@@ -201,6 +217,7 @@ gl_journal_model_set_matches (GlJournalModel      *model,
     g_return_if_fail (matches != NULL);
 
     gl_journal_model_stop_idle (model);
+    model->fetched_all = FALSE;
     if (model->entries->len > 0)
     {
         g_list_model_items_changed (G_LIST_MODEL (model), 0, model->entries->len, 0);
@@ -209,8 +226,7 @@ gl_journal_model_set_matches (GlJournalModel      *model,
 
     gl_journal_set_matches (model->journal, matches);
 
-    model->idle_source = g_idle_add_full (G_PRIORITY_LOW, gl_journal_model_fetch_entries, model, NULL);
-    g_object_notify_by_pspec (G_OBJECT (model), properties[PROP_LOADING]);
+    gl_journal_model_fetch_more_entries (model, FALSE);
 }
 
 /**
@@ -229,3 +245,33 @@ gl_journal_model_get_loading (GlJournalModel *model)
 
     return model->idle_source > 0;
 }
+
+/**
+ * gl_journal_model_fetch_more_entries:
+ * @model: a #GlJournalModel
+ * @all: whether to fetch all available entries
+ *
+ * @model doesn't loads all entries at once, but in batches. This
+ * function triggers it to load the next batch, or all remaining entries
+ * if @all is %TRUE.
+ */
+void
+gl_journal_model_fetch_more_entries (GlJournalModel *model,
+                                     gboolean        all)
+{
+    g_return_if_fail (GL_IS_JOURNAL_MODEL (model));
+
+    if (model->fetched_all)
+      return;
+
+    if (all)
+        model->n_entries_to_fetch = G_MAXUINT32;
+    else
+        model->n_entries_to_fetch = model->batch_size;
+
+    if (model->idle_source == 0)
+    {
+        model->idle_source = g_idle_add_full (G_PRIORITY_LOW, gl_journal_model_fetch_idle, model, NULL);
+        g_object_notify_by_pspec (G_OBJECT (model), properties[PROP_LOADING]);
+    }
+}
diff --git a/src/gl-journal-model.h b/src/gl-journal-model.h
index dbe8c5d..b21867b 100644
--- a/src/gl-journal-model.h
+++ b/src/gl-journal-model.h
@@ -14,4 +14,7 @@ void                    gl_journal_model_set_matches                    (GlJourn
 
 gboolean                gl_journal_model_get_loading                    (GlJournalModel *model);
 
+void                    gl_journal_model_fetch_more_entries             (GlJournalModel *model,
+                                                                         gboolean        all);
+
 #endif


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