From 7a07c80767950787601924b2b8091c8a0cb3371a Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 20 Oct 2010 13:31:46 +0200 Subject: Bug #630504 - Precache collate keys before sorting in EReflowModel --- widgets/text/e-reflow-model.c | 30 ++++++++++++++++++++++++++++-- widgets/text/e-reflow-model.h | 7 +++++-- widgets/text/e-reflow.c | 13 ++++++++++--- 3 files changed, 43 insertions(+), 7 deletions(-) (limited to 'widgets') diff --git a/widgets/text/e-reflow-model.c b/widgets/text/e-reflow-model.c index 6f8223ae9a..d7a5ffec48 100644 --- a/widgets/text/e-reflow-model.c +++ b/widgets/text/e-reflow-model.c @@ -108,25 +108,51 @@ e_reflow_model_incarnate (EReflowModel *e_reflow_model, gint n, GnomeCanvasGroup return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->incarnate (e_reflow_model, n, parent); } +/** + * e_reflow_model_create_cmp_cache: + * @e_reflow_model: The e-reflow-model to operate on + * + * Creates a compare cache for quicker sorting. The sorting function + * may not depend on the cache, but it should benefit from it if available. + * + * Returns: Newly created GHashTable with cached compare values. This will be + * automatically freed with g_hash_table_destroy() when no longer needed. + **/ +GHashTable * +e_reflow_model_create_cmp_cache (EReflowModel *e_reflow_model) +{ + g_return_val_if_fail (e_reflow_model != NULL, NULL); + g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), NULL); + + if (!E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->create_cmp_cache) + return NULL; + + return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->create_cmp_cache (e_reflow_model); +} + /** * e_reflow_model_compare: * @e_reflow_model: The e-reflow-model to operate on * @n1: The first item to compare * @n2: The second item to compare + * @cmp_cache: #GHashTable of cached compare values, created by + * e_reflow_model_create_cmp_cache(). This can be NULL, when + * caching is not available, even when @e_reflow_model defines + * the create_cmp_cache function. * * Compares item n1 and item n2 to see which should come first. * * Returns: strcmp like semantics for the comparison value. */ gint -e_reflow_model_compare (EReflowModel *e_reflow_model, gint n1, gint n2) +e_reflow_model_compare (EReflowModel *e_reflow_model, gint n1, gint n2, GHashTable *cmp_cache) { #if 0 g_return_val_if_fail (e_reflow_model != NULL, 0); g_return_val_if_fail (E_IS_REFLOW_MODEL (e_reflow_model), 0); #endif - return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->compare (e_reflow_model, n1, n2); + return E_REFLOW_MODEL_GET_CLASS (e_reflow_model)->compare (e_reflow_model, n1, n2, cmp_cache); } /** diff --git a/widgets/text/e-reflow-model.h b/widgets/text/e-reflow-model.h index ebbf3c1f75..f6f096df0a 100644 --- a/widgets/text/e-reflow-model.h +++ b/widgets/text/e-reflow-model.h @@ -51,7 +51,8 @@ typedef struct { gint (*count) (EReflowModel *etm); gint (*height) (EReflowModel *etm, gint n, GnomeCanvasGroup *parent); GnomeCanvasItem *(*incarnate) (EReflowModel *etm, gint n, GnomeCanvasGroup *parent); - gint (*compare) (EReflowModel *etm, gint n1, gint n2); + GHashTable * (*create_cmp_cache) (EReflowModel *etm); + gint (*compare) (EReflowModel *etm, gint n1, gint n2, GHashTable *cmp_cache); void (*reincarnate) (EReflowModel *etm, gint n, GnomeCanvasItem *item); /* @@ -83,9 +84,11 @@ gint e_reflow_model_height (EReflowModel *e_reflow_mod GnomeCanvasItem *e_reflow_model_incarnate (EReflowModel *e_reflow_model, gint n, GnomeCanvasGroup *parent); +GHashTable * e_reflow_model_create_cmp_cache (EReflowModel *e_reflow_model); gint e_reflow_model_compare (EReflowModel *e_reflow_model, gint n1, - gint n2); + gint n2, + GHashTable *cmp_cache); void e_reflow_model_reincarnate (EReflowModel *e_reflow_model, gint n, GnomeCanvasItem *item); diff --git a/widgets/text/e-reflow.c b/widgets/text/e-reflow.c index d7522d6344..a796d92bba 100644 --- a/widgets/text/e-reflow.c +++ b/widgets/text/e-reflow.c @@ -74,11 +74,18 @@ enum { static guint signals[LAST_SIGNAL] = {0, }; +static GHashTable * +er_create_cmp_cache (gpointer user_data) +{ + EReflow *reflow = user_data; + return e_reflow_model_create_cmp_cache (reflow->model); +} + static gint -er_compare (gint i1, gint i2, gpointer user_data) +er_compare (gint i1, gint i2, GHashTable *cmp_cache, gpointer user_data) { EReflow *reflow = user_data; - return e_reflow_model_compare (reflow->model, i1, i2); + return e_reflow_model_compare (reflow->model, i1, i2, cmp_cache); } static gint @@ -1594,7 +1601,7 @@ e_reflow_init (EReflow *reflow) reflow->set_scroll_adjustments_id = 0; reflow->selection = E_SELECTION_MODEL (e_selection_model_simple_new ()); - reflow->sorter = e_sorter_array_new (er_compare, reflow); + reflow->sorter = e_sorter_array_new (er_create_cmp_cache, er_compare, reflow); g_object_set (reflow->selection, "sorter", reflow->sorter, -- cgit