[evolution/webkit-composer: 101/147] Optimize e_spell_checker_list_available_dicts()
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit-composer: 101/147] Optimize e_spell_checker_list_available_dicts()
- Date: Mon, 21 Jan 2013 02:18:37 +0000 (UTC)
commit d597b6ce01f2a12824245895e5afe2196efae0a4
Author: Dan VrÃtil <dvratil redhat com>
Date: Sun Dec 9 21:48:00 2012 +0100
Optimize e_spell_checker_list_available_dicts()
Use a static cache to store all listed dictionaries to minimize number
of enchant_broker_list_dicts() calls.
Possibly fixes bug #689626
e-util/e-editor-actions.c | 3 -
e-util/e-spell-checker.c | 77 +++++++++++++++++++-------------------
e-util/e-spell-checker.h | 2 +-
modules/mail/em-composer-prefs.c | 3 +-
4 files changed, 41 insertions(+), 44 deletions(-)
---
diff --git a/e-util/e-editor-actions.c b/e-util/e-editor-actions.c
index 6fb61f5..7dc3e31 100644
--- a/e-util/e-editor-actions.c
+++ b/e-util/e-editor-actions.c
@@ -1699,8 +1699,6 @@ editor_actions_setup_languages_menu (EEditor *editor)
e_spell_dictionary_get_code (dictionary),
e_spell_dictionary_get_code (dictionary),
GTK_UI_MANAGER_AUTO, FALSE);
-
- g_object_unref (dictionary);
}
g_list_free (available_dicts);
@@ -1776,7 +1774,6 @@ editor_actions_setup_spell_check_menu (EEditor *editor)
action_name, action_name,
GTK_UI_MANAGER_AUTO, FALSE);
- g_object_unref (dictionary);
g_free (action_label);
g_free (action_name);
}
diff --git a/e-util/e-spell-checker.c b/e-util/e-spell-checker.c
index f10438b..de4317b 100644
--- a/e-util/e-spell-checker.c
+++ b/e-util/e-spell-checker.c
@@ -38,9 +38,12 @@ G_DEFINE_TYPE_EXTENDED (
WEBKIT_TYPE_SPELL_CHECKER,
e_spell_checker_init_webkit_checker))
+
+static ESpellChecker *s_instance = NULL;
+
struct _ESpellCheckerPrivate {
GList *active;
-
+ GHashTable *dictionaries_cache;
EnchantBroker *broker;
};
@@ -248,7 +251,7 @@ wksc_update_languages (WebKitSpellChecker *webkit_checker,
}
e_spell_checker_set_active_dictionaries (checker, dictionaries);
- g_list_free_full (dictionaries, g_object_unref);
+ g_list_free (dictionaries);
}
@@ -344,19 +347,18 @@ e_spell_checker_init (ESpellChecker *checker)
checker, E_TYPE_SPELL_CHECKER, ESpellCheckerPrivate);
checker->priv->broker = enchant_broker_init ();
+ checker->priv->dictionaries_cache = NULL;
}
ESpellChecker *
-e_spell_checker_new (void)
+e_spell_checker_instance (void)
{
- return g_object_new (E_TYPE_SPELL_CHECKER, NULL);
-}
-
+ if (s_instance == NULL) {
+ s_instance = g_object_new (E_TYPE_SPELL_CHECKER, NULL);
+ }
-typedef struct {
- ESpellChecker *checker;
- GList *dicts;
-} ListAvailDictsData;
+ return s_instance;
+}
static void
list_enchant_dicts (const char * const lang_tag,
@@ -365,16 +367,18 @@ list_enchant_dicts (const char * const lang_tag,
const char * const provider_file,
void * user_data)
{
- ListAvailDictsData *data = user_data;
+ ESpellChecker *checker = user_data;
EnchantDict *dict;
- dict = enchant_broker_request_dict (data->checker->priv->broker, lang_tag);
+ dict = enchant_broker_request_dict (checker->priv->broker, lang_tag);
if (dict) {
ESpellDictionary *e_dict;
- e_dict = e_spell_dictionary_new (data->checker, dict);
+ e_dict = e_spell_dictionary_new (checker, dict);
- data->dicts = g_list_prepend (data->dicts, e_dict);
+ g_hash_table_insert (
+ checker->priv->dictionaries_cache,
+ (gpointer) e_spell_dictionary_get_code (e_dict), e_dict);
}
}
@@ -386,24 +390,24 @@ list_enchant_dicts (const char * const lang_tag,
* Returns list of all dictionaries available to the actual
* spell-checking backend.
*
- * Return value: a #GList of #ESpellDictionary. Free the list using g_list_free()
- * when not needed anymore.
+ * Return value: new copy of #GList of #ESpellDictionary. The dictionaries are
+ * owned by the @checker and should not be free'd. The list should be free'd
+ * using g_list_free() when not neede anymore. [transfer-list]
*/
GList *
e_spell_checker_list_available_dicts (ESpellChecker *checker)
{
- ESpellChecker *e_checker;
- ListAvailDictsData data = { 0 };
-
g_return_val_if_fail (E_IS_SPELL_CHECKER (checker), NULL);
- e_checker = E_SPELL_CHECKER (checker);
+ if (checker->priv->dictionaries_cache == NULL) {
- data.checker = e_checker;
- enchant_broker_list_dicts (
- e_checker->priv->broker, list_enchant_dicts, &data);
+ checker->priv->dictionaries_cache = g_hash_table_new_full (
+ g_str_hash, g_str_equal, NULL, g_object_unref);
+ enchant_broker_list_dicts (
+ checker->priv->broker, list_enchant_dicts, checker);
+ }
- return g_list_reverse (data.dicts);
+ return g_hash_table_get_values (checker->priv->dictionaries_cache);
}
/**
@@ -420,32 +424,29 @@ ESpellDictionary *
e_spell_checker_lookup_dictionary (ESpellChecker *checker,
const gchar *language_code)
{
- ESpellChecker *e_checker;
- ESpellDictionary *e_dict;
+ ESpellDictionary *e_dict = NULL;
+ GList *dicts;
g_return_val_if_fail (E_IS_SPELL_CHECKER (checker), NULL);
- e_checker = E_SPELL_CHECKER (checker);
-
- e_dict = NULL;
+ /* If the cache has not yet been initialized, do so - we will need
+ * it anyway, Otherwise is this call very cheap */
+ dicts = e_spell_checker_list_available_dicts (checker);
if (!language_code) {
- GList *dicts = e_spell_checker_list_available_dicts (checker);
-
if (dicts) {
e_dict = g_object_ref (dicts->data);
- g_list_free_full (dicts, g_object_unref);
}
} else {
- EnchantDict *dict;
- dict = enchant_broker_request_dict (
- e_checker->priv->broker, language_code);
- if (dict) {
- e_dict = e_spell_dictionary_new (checker, dict);
+ e_dict = g_hash_table_lookup (
+ checker->priv->dictionaries_cache, language_code);
+ if (e_dict) {
+ g_object_ref (e_dict);
}
}
- return e_dict;
+ g_list_free (dicts);
+ return NULL;
}
/**
diff --git a/e-util/e-spell-checker.h b/e-util/e-spell-checker.h
index 3a38048..ff3b6eb 100644
--- a/e-util/e-spell-checker.h
+++ b/e-util/e-spell-checker.h
@@ -60,7 +60,7 @@ struct _ESpellCheckerClass {
GType e_spell_checker_get_type (void);
-ESpellChecker * e_spell_checker_new (void);
+ESpellChecker * e_spell_checker_instance (void);
GList * e_spell_checker_list_available_dicts
(ESpellChecker *checker);
diff --git a/modules/mail/em-composer-prefs.c b/modules/mail/em-composer-prefs.c
index e9cea49..cf142d4 100644
--- a/modules/mail/em-composer-prefs.c
+++ b/modules/mail/em-composer-prefs.c
@@ -126,7 +126,6 @@ composer_prefs_dispose (GObject *object)
EMComposerPrefs *prefs = (EMComposerPrefs *) object;
g_clear_object (&prefs->builder);
- g_clear_object (&prefs->spell_checker);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (em_composer_prefs_parent_class)->dispose (object);
@@ -332,7 +331,7 @@ em_composer_prefs_construct (EMComposerPrefs *prefs,
e_load_ui_builder_definition (prefs->builder, "mail-config.ui");
- prefs->spell_checker = e_spell_checker_new ();
+ prefs->spell_checker = e_spell_checker_instance();
/** @HookPoint-EMConfig: Mail Composer Preferences
* @Id: org.gnome.evolution.mail.composerPrefs
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]