[evolution/wip/webkit2] [EMailLabelListStore] Avoid circular dependency in a tag cache
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] [EMailLabelListStore] Avoid circular dependency in a tag cache
- Date: Wed, 2 Mar 2016 16:59:03 +0000 (UTC)
commit 5c821191a0801aece4b096c3d61553cf6b0467da
Author: Milan Crha <mcrha redhat com>
Date: Fri Nov 13 17:11:25 2015 +0100
[EMailLabelListStore] Avoid circular dependency in a tag cache
The store has its own cache of tags for quicker lookup, but this
cache used GtkTreeRowReference-s, which reference the model, thus
it made circular dependency and the store was never freed. Using
place GtkTreeIter pointer in the cache works too, one only needs
to do more often manual updates of it.
mail/e-mail-label-list-store.c | 83 ++++++++++++++++++----------------------
1 files changed, 37 insertions(+), 46 deletions(-)
---
diff --git a/mail/e-mail-label-list-store.c b/mail/e-mail-label-list-store.c
index cb477b2..774495a 100644
--- a/mail/e-mail-label-list-store.c
+++ b/mail/e-mail-label-list-store.c
@@ -44,7 +44,7 @@ enum {
static guint signals[LAST_SIGNAL];
struct _EMailLabelListStorePrivate {
- GHashTable *tag_index;
+ GHashTable *tag_index; /* gchar *tag_name ~> GtkTreeIter * */
GSettings *mail_settings;
guint idle_changed_id;
};
@@ -110,6 +110,29 @@ mail_label_list_store_encode_label (const gchar *label_name,
}
static void
+mail_label_list_store_fill_tag_index (EMailLabelListStore *store)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_hash_table_remove_all (store->priv->tag_index);
+
+ model = GTK_TREE_MODEL (store);
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return;
+
+ do {
+ gchar *tag;
+
+ tag = e_mail_label_list_store_get_tag (store, &iter);
+ if (!tag)
+ continue;
+
+ g_hash_table_insert (store->priv->tag_index, tag, gtk_tree_iter_copy (&iter));
+ } while (gtk_tree_model_iter_next (model, &iter));
+}
+
+static void
mail_label_list_store_ensure_defaults (EMailLabelListStore *store)
{
gint ii;
@@ -266,6 +289,8 @@ labels_model_changed_idle_cb (gpointer user_data)
store->priv->mail_settings,
labels_settings_changed_cb, store);
+ mail_label_list_store_fill_tag_index (store);
+
g_signal_emit (store, signals[CHANGED], 0);
return FALSE;
@@ -276,6 +301,8 @@ labels_model_changed_cb (EMailLabelListStore *store)
{
g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store));
+ mail_label_list_store_fill_tag_index (store);
+
/* do the actual save and signal emission on idle,
* to accumulate as many changes as possible */
if (!store->priv->idle_changed_id)
@@ -327,6 +354,8 @@ labels_settings_changed_cb (GSettings *settings,
if (g_hash_table_size (changed_labels) == 0) {
g_hash_table_destroy (changed_labels);
g_strfreev (strv);
+
+ mail_label_list_store_fill_tag_index (store);
return;
}
@@ -349,6 +378,8 @@ labels_settings_changed_cb (GSettings *settings,
g_signal_handlers_unblock_by_func (
store, labels_model_changed_cb, store);
+
+ mail_label_list_store_fill_tag_index (store);
}
static void
@@ -387,32 +418,6 @@ mail_label_list_store_constructed (GObject *object)
}
static void
-mail_label_list_store_row_inserted (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter)
-{
- EMailLabelListStore *store;
- GtkTreeRowReference *reference;
- GHashTable *tag_index;
- gchar *tag;
-
- store = E_MAIL_LABEL_LIST_STORE (model);
- tag = e_mail_label_list_store_get_tag (store, iter);
- g_return_if_fail (tag != NULL);
-
- /* Hash table takes ownership of both tag and reference. */
- tag_index = store->priv->tag_index;
- reference = gtk_tree_row_reference_new (model, path);
- g_hash_table_insert (tag_index, tag, reference);
-
- /* We don't need to do anything special for row deletion.
- * The reference will automatically become invalid (that's
- * why we're storing references and not iterators or paths),
- * so garbage collection is not important. We'll do it
- * lazily. */
-}
-
-static void
e_mail_label_list_store_class_init (EMailLabelListStoreClass *class)
{
GObjectClass *object_class;
@@ -439,7 +444,6 @@ e_mail_label_list_store_class_init (EMailLabelListStoreClass *class)
static void
e_mail_label_list_store_interface_init (GtkTreeModelIface *iface)
{
- iface->row_inserted = mail_label_list_store_row_inserted;
}
static void
@@ -451,7 +455,7 @@ e_mail_label_list_store_init (EMailLabelListStore *store)
tag_index = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
- (GDestroyNotify) gtk_tree_row_reference_free);
+ (GDestroyNotify) gtk_tree_iter_free);
store->priv = E_MAIL_LABEL_LIST_STORE_GET_PRIVATE (store);
store->priv->tag_index = tag_index;
@@ -658,31 +662,18 @@ e_mail_label_list_store_lookup (EMailLabelListStore *store,
const gchar *tag,
GtkTreeIter *iter)
{
- GtkTreeRowReference *reference;
- GHashTable *tag_index;
- GtkTreeModel *model;
- GtkTreePath *path;
+ GtkTreeIter *stored_iter;
g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), FALSE);
g_return_val_if_fail (tag != NULL, FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
- tag_index = store->priv->tag_index;
- reference = g_hash_table_lookup (tag_index, tag);
+ stored_iter = g_hash_table_lookup (store->priv->tag_index, tag);
- if (reference == NULL)
+ if (!stored_iter)
return FALSE;
- if (!gtk_tree_row_reference_valid (reference)) {
- /* Garbage collect the dead reference. */
- g_hash_table_remove (tag_index, tag);
- return FALSE;
- }
-
- model = gtk_tree_row_reference_get_model (reference);
- path = gtk_tree_row_reference_get_path (reference);
- gtk_tree_model_get_iter (model, iter, path);
- gtk_tree_path_free (path);
+ *iter = *stored_iter;
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]