[gnumeric] Evaluation: manage caches properly.



commit be2348db4b2a25525cd3901bcefa1557314feaa8
Author: Morten Welinder <terra gnome org>
Date:   Thu May 14 15:03:39 2009 -0400

    Evaluation: manage caches properly.
---
 ChangeLog           |   17 +++++++++++++----
 src/application.c   |   17 +++++++++++++++--
 src/application.h   |    3 ++-
 src/clipboard.c     |    7 ++++---
 src/dependent.c     |    6 ++++--
 src/expr.c          |    7 ++++++-
 src/validation.c    |   20 +++++++++++---------
 src/workbook-view.c |   24 ++++++++----------------
 8 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 13a35b5..ee33221 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,18 @@
 2009-05-14  Morten Welinder  <terra gnome org>
 
-	* src/application.c (gnm_app_recalc_finished): New function.
-	* src/dependent.c (workbook_recalc): Use gnm_app_recalc_finished.
-	* src/workbook-view.c (wb_view_auto_expr_recalc): Call
-	gnm_app_recalc_finished.
+	* src/dependent.c (workbook_recalc): Wrap whole evaluation in
+	calls to gnm_app_recalc_start and gnm_app_recalc_finish.
+
+	* src/expr.c (gnm_expr_top_eval): Wrap gnm_expr_eval call in calls
+	to gnm_app_recalc_start and gnm_app_recalc_finish.
+
+	* src/clipboard.c (paste_cell_with_operation): Create a GnmExprTop
+	and use that for evaluation.
+	* src/validation.c (validation_eval): Ditto.
+	* src/workbook-view.c (wb_view_auto_expr_recalc): Ditto.  Simplify.
+
+	* src/application.c (gnm_app_recalc_start, gnm_app_recalc_finish):
+	New functions.
 
 	* src/commands.c (cmd_so_set_adjustment): Handle h/v too.  All
 	callers changed.
diff --git a/src/application.c b/src/application.c
index e9cea69..90dbc4e 100644
--- a/src/application.c
+++ b/src/application.c
@@ -67,6 +67,9 @@ struct _GnmApp {
 
 	GList		*workbook_list;
 
+	/* Recalculation manager.  */
+	int             recalc_count;
+
 #ifdef HAVE_GTK_RECENT_MANAGER_GET_DEFAULT
 	GtkRecentManager *recent;
 	gulong           recent_sig;
@@ -867,7 +870,17 @@ _gnm_app_flag_windows_changed (void)
 /**********************************************************************/
 
 void
-gnm_app_recalc_finished (void)
+gnm_app_recalc_start (void)
+{
+	g_return_if_fail (app->recalc_count >= 0);
+	app->recalc_count++;
+}
+
+void
+gnm_app_recalc_finish (void)
 {
-	g_signal_emit_by_name (gnm_app_get_app (), "recalc-finished");
+	g_return_if_fail (app->recalc_count > 0);
+	app->recalc_count--;
+	if (app->recalc_count == 0)
+		g_signal_emit_by_name (gnm_app_get_app (), "recalc-finished");
 }
diff --git a/src/application.h b/src/application.h
index ed96d33..abbf4a4 100644
--- a/src/application.h
+++ b/src/application.h
@@ -27,7 +27,8 @@ gboolean     gnm_app_workbook_foreach	   (GnmWbIterFunc func, gpointer data);
 GSList      *gnm_app_history_get_list	   (int max_elements);
 void	     gnm_app_history_add	   (char const *filename, const char *mimetype);
 
-void         gnm_app_recalc_finished       (void);
+void         gnm_app_recalc_start          (void);
+void         gnm_app_recalc_finish         (void);
 
 /* GtkFileFilter */
 void        *gnm_app_create_opener_filter (void);
diff --git a/src/clipboard.c b/src/clipboard.c
index 14b2b9a..4754644 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -138,12 +138,13 @@ paste_cell_with_operation (Sheet *dst_sheet,
 			gnm_expr_new_constant (value_dup (dst->value)),
 			op,
 			gnm_expr_new_constant (value_dup (src->val)));
+		GnmExprTop const *texpr = gnm_expr_top_new (expr);
 
 		eval_pos_init_cell (&pos, dst);
 		pos.dep = NULL; /* no dynamic deps */
-		value = gnm_expr_eval (expr, &pos,
-				       GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
-		gnm_expr_free (expr);
+		value = gnm_expr_top_eval (texpr, &pos,
+					   GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+		gnm_expr_top_unref (texpr);
 		gnm_cell_set_value (dst, value);
 	}
 }
diff --git a/src/dependent.c b/src/dependent.c
index bd2bef5..8cd0361 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -2645,6 +2645,8 @@ workbook_recalc (Workbook *wb)
 
 	g_return_if_fail (IS_WORKBOOK (wb));
 
+	gnm_app_recalc_start ();
+
 	WORKBOOK_FOREACH_DEPENDENT (wb, dep, {
 		if (dependent_needs_recalc (dep)) {
 			redraw = TRUE;
@@ -2652,6 +2654,8 @@ workbook_recalc (Workbook *wb)
 		}
 	});
 
+	gnm_app_recalc_finish ();
+
 	/*
 	 * This is a bit of a band-aid.  If anything is recalculated, we
 	 * force a full redraw.  The alternative is to ask for updates
@@ -2659,8 +2663,6 @@ workbook_recalc (Workbook *wb)
 	 * expensive.
 	 */
 	if (redraw) {
-		gnm_app_recalc_finished ();
-
 		WORKBOOK_FOREACH_SHEET (wb, sheet, {
 			SHEET_FOREACH_VIEW (sheet, sv, sv_flag_selection_change (sv););
 			sheet_redraw_all (sheet, FALSE);});
diff --git a/src/expr.c b/src/expr.c
index 017260c..60fdccc 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2974,9 +2974,14 @@ gnm_expr_top_eval (GnmExprTop const *texpr,
 		   GnmEvalPos const *pos,
 		   GnmExprEvalFlags flags)
 {
+	GnmValue *res;
 	g_return_val_if_fail (IS_GNM_EXPR_TOP (texpr), NULL);
 
-	return gnm_expr_eval (texpr->expr, pos, flags);
+	gnm_app_recalc_start ();
+	res = gnm_expr_eval (texpr->expr, pos, flags);
+	gnm_app_recalc_finish ();
+
+	return res;
 }
 
 /**
diff --git a/src/validation.c b/src/validation.c
index a0037a7..fe9d7e1 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -482,24 +482,26 @@ validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
 
 	nok = 0;
 	for (i = 0; i < opinfo[v->op].nops; i++) {
-		GnmExprTop const *texpr = v->texpr[i];
-		GnmExpr const *expr;
+		GnmExprTop const *texpr_i = v->texpr[i];
+		GnmExpr const *texpr;
 		GnmValue *cres;
 
-		if (!texpr) {
+		if (!texpr_i) {
 			nok++;
 			continue;
 		}
 
-		expr = gnm_expr_new_binary
-			(gnm_expr_new_constant (value_new_float (x)),
-			 opinfo[v->op].ops[i],
-			 gnm_expr_copy (texpr->expr));
-		cres = gnm_expr_eval (expr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
+		texpr = gnm_expr_top_new
+			(gnm_expr_new_binary
+			 (gnm_expr_new_constant (value_new_float (x)),
+			  opinfo[v->op].ops[i],
+			  gnm_expr_copy (texpr_i->expr)));
+		cres = gnm_expr_top_eval
+			(texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
 		if (value_get_as_bool (cres, NULL))
 			nok++;
 		value_release (cres);
-		gnm_expr_free (expr);
+		gnm_expr_top_unref (texpr);
 	}
 
 	if (nok < opinfo[v->op].ntrue)
diff --git a/src/workbook-view.c b/src/workbook-view.c
index 6238180..6819a96 100644
--- a/src/workbook-view.c
+++ b/src/workbook-view.c
@@ -465,12 +465,11 @@ accumulate_regions (SheetView *sv,  GnmRange const *r, gpointer closure)
 void
 wb_view_auto_expr_recalc (WorkbookView *wbv)
 {
-	GnmFuncEvalInfo ei;
 	GnmEvalPos      ep;
 	GnmExprList	*selection = NULL;
 	GnmValue	*v;
 	SheetView	*sv;
-	GnmExpr const   *expr;
+	GnmExprTop const *texpr;
 
 	g_return_if_fail (IS_WORKBOOK_VIEW (wbv));
 
@@ -482,12 +481,11 @@ wb_view_auto_expr_recalc (WorkbookView *wbv)
 
 	sv_selection_apply (sv, &accumulate_regions, FALSE, &selection);
 
-	expr = gnm_expr_new_funcall (wbv->auto_expr_func, selection);
+	texpr = gnm_expr_top_new
+		(gnm_expr_new_funcall (wbv->auto_expr_func, selection));
 
-	ei.pos = eval_pos_init_sheet (&ep, wbv->current_sheet);
-	ei.func_call = &expr->func;
-	v = function_call_with_exprs (&ei, 0);
-	gnm_app_recalc_finished ();
+	eval_pos_init_sheet (&ep, wbv->current_sheet);
+	v = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
 
 	if (v) {
 		GString *str = g_string_new (wbv->auto_expr_descr);
@@ -497,14 +495,9 @@ wb_view_auto_expr_recalc (WorkbookView *wbv)
 		g_string_append_c (str, '=');
 		if (!wbv->auto_expr_use_max_precision) {
 			format = VALUE_FMT (v);
-			if (!format) {
-				const GnmExprTop *fcall =
-					gnm_expr_top_new (expr);
-				expr = NULL;
+			if (!format)
 				format = tmp_format =
-					auto_style_format_suggest (fcall, ei.pos);
-				gnm_expr_top_unref (fcall);
-			}
+					auto_style_format_suggest (texpr, &ep);
 		}
 
 		if (format) {
@@ -524,8 +517,7 @@ wb_view_auto_expr_recalc (WorkbookView *wbv)
 		g_object_set (wbv, "auto-expr-text", "Internal ERROR", NULL);
 	}
 
-	if (expr)
-		gnm_expr_free (expr);
+	gnm_expr_top_unref (texpr);
 }
 
 /* perform whatever initialization of a control that is necessary when it



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