[gnome-logs] journalmodel: load entries in batches
- From: Lars Uebernickel <larsu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-logs] journalmodel: load entries in batches
- Date: Thu, 19 Feb 2015 17:24:50 +0000 (UTC)
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]