[gnumeric] Conditional formatting: make proper hash function.



commit 6e6ec4a38b71d9b71c178d0873a3a87b170c8b25
Author: Morten Welinder <terra gnome org>
Date:   Thu May 31 14:51:13 2012 -0400

    Conditional formatting: make proper hash function.

 ChangeLog              |    3 +++
 src/mstyle.c           |   11 +++++++++--
 src/style-conditions.c |   34 ++++++++++++++++++++++++++++++++++
 src/style-conditions.h |    2 ++
 4 files changed, 48 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 72d6799..d6a06ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,14 @@
 2012-05-31  Morten Welinder  <terra gnome org>
 
+	* src/mstyle.c (gnm_style_update): Use gnm_style_conditions_hash.
+
 	* src/style-conditions.c (gnm_style_conditions_new): Add new sheet
 	argument.  All callers changed.
 	(gnm_style_conditions_insert): Verify that sheets match between
 	objects.
 	(gnm_style_cond_new): Add new sheet argument.  All callers
 	changed.  Initialize managed dependent.
+	(gnm_style_conditions_hash): New function.
 
 	* src/style-conditions.h (GnmStyleCond): Store expressions as
 	managed dependents.
diff --git a/src/mstyle.c b/src/mstyle.c
index daec476..8c50477 100644
--- a/src/mstyle.c
+++ b/src/mstyle.c
@@ -294,8 +294,15 @@ gnm_style_update (GnmStyle *style)
 		hash ^= GPOINTER_TO_UINT (style->input_msg);
 	MIX (hash);
 
-	if (elem_is_set (style, MSTYLE_CONDITIONS))
-		hash ^= GPOINTER_TO_UINT (style->conditions);
+	if (elem_is_set (style, MSTYLE_CONDITIONS)) {
+		/*
+		 * The hash used must not depend on the expressions inside
+		 * the conditions.
+		 */
+		hash ^= style->conditions
+			? gnm_style_conditions_hash (style->conditions)
+			: 1u;
+	}
 	MIX (hash);
 
 	style->hash_key = (guint32)hash;
diff --git a/src/style-conditions.c b/src/style-conditions.c
index 95a6d2c..b235c5b 100644
--- a/src/style-conditions.c
+++ b/src/style-conditions.c
@@ -269,6 +269,40 @@ gnm_style_conditions_dup (GnmStyleConditions const *sc)
 	return dup;
 }
 
+#define MIX(H) do {				\
+  H *= G_GUINT64_CONSTANT(123456789012345);	\
+  H ^= (H >> 31);				\
+} while (0)
+
+guint32
+gnm_style_conditions_hash (GnmStyleConditions const *sc)
+{
+	guint64 hash = 42;
+	GPtrArray const *ga;
+	unsigned ui;
+
+	/*
+	 * Note: this hash must not depend on the expressions stored
+	 * in ->deps.  And probably not on the sheet either.
+	 */
+
+	g_return_val_if_fail (sc != NULL, 0u);
+
+	ga = gnm_style_conditions_details (sc);
+	for (ui = 0; ui < (ga ? ga->len : 0u); ui++) {
+		GnmStyleCond *cond = g_ptr_array_index (ga, ui);
+		if (cond->overlay)
+			hash ^= gnm_style_hash_XL (cond->overlay);
+		MIX (hash);
+		hash ^= cond->op;
+		MIX (hash);
+	}
+
+	return hash;
+}
+
+#undef MIX
+
 Sheet *
 gnm_style_conditions_get_sheet (GnmStyleConditions const *sc)
 {
diff --git a/src/style-conditions.h b/src/style-conditions.h
index 6dbf1d1..468c5f1 100644
--- a/src/style-conditions.h
+++ b/src/style-conditions.h
@@ -77,6 +77,8 @@ Sheet      *gnm_style_conditions_get_sheet (GnmStyleConditions const *sc);
 void        gnm_style_conditions_set_sheet (GnmStyleConditions *sc,
 					    Sheet *sheet);
 
+guint32     gnm_style_conditions_hash      (GnmStyleConditions const *sc);
+
 G_END_DECLS
 
 #endif /* _GNM_STYLE_CONDITIONS_H_ */



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