gnumeric r16495 - in trunk: . plugins/fn-lookup src
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16495 - in trunk: . plugins/fn-lookup src
- Date: Wed, 9 Apr 2008 00:48:19 +0100 (BST)
Author: mortenw
Date: Wed Apr 9 00:48:18 2008
New Revision: 16495
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16495&view=rev
Log:
Fix float case of VLOOKUP/HLOOKUP/MATCH too.
2008-04-08 Morten Welinder <terra gnome org>
* src/mathfunc.c (gnm_float_hash, gnm_float_equal): Moved from
rangefunc.c. Made public.
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/plugins/fn-lookup/functions.c
trunk/src/mathfunc.c
trunk/src/mathfunc.h
trunk/src/rangefunc.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Wed Apr 9 00:48:18 2008
@@ -65,7 +65,8 @@
* Fix check for bogus xls files. [#524926]
* Fix CONCATENATE's empty case.
* Improve performance of analysis tools for large ranges.
- * Fix performance of repeated [VH]LOOKUP with constant data range. [#525875]
+ * Fix performance repeated VLOOKUP/HLOOKUP/MATCH with constant
+ data range. [#525875]
Nick Lamb:
* Honour detachable-toolbar preference. [#321867]
Modified: trunk/plugins/fn-lookup/functions.c
==============================================================================
--- trunk/plugins/fn-lookup/functions.c (original)
+++ trunk/plugins/fn-lookup/functions.c Wed Apr 9 00:48:18 2008
@@ -38,6 +38,7 @@
#include <expr-impl.h>
#include <application.h>
#include <expr-name.h>
+#include <mathfunc.h>
#include <parse-util.h>
#include <gnm-i18n.h>
@@ -50,6 +51,7 @@
GNM_PLUGIN_MODULE_HEADER;
static GHashTable *lookup_string_cache;
+static GHashTable *lookup_float_cache;
static void
clear_caches (void)
@@ -58,12 +60,27 @@
g_hash_table_destroy (lookup_string_cache);
lookup_string_cache = NULL;
}
+ if (lookup_float_cache) {
+ g_hash_table_destroy (lookup_float_cache);
+ lookup_float_cache = NULL;
+ }
}
static GHashTable *
-get_string_cache (const GnmSheetRange *sr)
+get_cache (GnmFuncEvalInfo *ei, GnmValue const *data, gboolean stringp)
{
+ GnmSheetRange sr;
GHashTable *h;
+ Sheet *end_sheet;
+ GnmRangeRef const *rr;
+
+ if (data->type != VALUE_CELLRANGE)
+ return NULL;
+ rr = value_get_rangeref (data);
+
+ gnm_rangeref_normalize (rr, ei->pos, &sr.sheet, &end_sheet, &sr.range);
+ if (sr.sheet != end_sheet)
+ return NULL;
if (!lookup_string_cache) {
lookup_string_cache = g_hash_table_new_full
@@ -73,12 +90,18 @@
(GDestroyNotify)g_hash_table_destroy);
}
- h = g_hash_table_lookup (lookup_string_cache, sr);
+ h = g_hash_table_lookup (lookup_string_cache, &sr);
if (!h) {
- h = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
+ if (stringp)
+ h = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free, NULL);
+ else
+ h = g_hash_table_new_full ((GHashFunc)gnm_float_hash,
+ (GEqualFunc)gnm_float_equal,
+ g_free, NULL);
g_hash_table_insert (lookup_string_cache,
- gnm_sheet_range_dup (sr), h);
+ gnm_sheet_range_dup (&sr), h);
}
return h;
@@ -198,25 +221,15 @@
gpointer pres;
char *sc;
gboolean found;
- GnmRangeRef const *rr;
- Sheet *start_sheet, *end_sheet;
- GnmSheetRange sr;
- if (data->type != VALUE_CELLRANGE)
- return -2;
- rr = value_get_rangeref (data);
-
- gnm_rangeref_normalize (rr, ei->pos, &start_sheet, &end_sheet, &sr.range);
- if (start_sheet != end_sheet)
+ h = get_cache (ei, data, TRUE);
+ if (!h)
return -2;
/* We need to do this early before calls to value_peek_string gets
called too often. */
sc = g_utf8_casefold (s, -1);
- sr.sheet = start_sheet;
- h = get_string_cache (&sr);
-
if (g_hash_table_size (h) == 0) {
int lp, length = calc_length (data, ei->pos, vertical);
@@ -224,7 +237,7 @@
GnmValue const *v = get_elem (data, lp, ei->pos, vertical);
char *vc;
- if (!VALUE_IS_STRING (v))
+ if (!v || !VALUE_IS_STRING (v))
continue;
vc = g_utf8_casefold (value_peek_string (v), -1);
@@ -242,6 +255,44 @@
}
static int
+find_index_linear_equal_float (GnmFuncEvalInfo *ei,
+ gnm_float f, GnmValue const *data,
+ gboolean vertical)
+{
+ GHashTable *h;
+ gpointer pres;
+ gboolean found;
+
+ h = get_cache (ei, data, FALSE);
+ if (!h)
+ return -2;
+
+ if (g_hash_table_size (h) == 0) {
+ int lp, length = calc_length (data, ei->pos, vertical);
+
+ for (lp = 0; lp < length; lp++) {
+ GnmValue const *v = get_elem (data, lp, ei->pos, vertical);
+ gnm_float f2;
+
+ if (!v || !VALUE_IS_NUMBER (v))
+ continue;
+
+ f2 = value_get_as_float (v);
+
+ if (!g_hash_table_lookup_extended (h, &f2, NULL, NULL))
+ g_hash_table_insert
+ (h,
+ g_memdup (&f2, sizeof (f2)),
+ GINT_TO_POINTER (lp));
+ }
+ }
+
+ found = g_hash_table_lookup_extended (h, &f, NULL, &pres);
+
+ return found ? GPOINTER_TO_INT (pres) : -1;
+}
+
+static int
find_index_linear (GnmFuncEvalInfo *ei,
GnmValue const *find, GnmValue const *data,
gint type, gboolean vertical)
@@ -257,6 +308,13 @@
return i;
}
+ if (VALUE_IS_NUMBER (find) && type == 0) {
+ gnm_float f = value_get_as_float (find);
+ int i = find_index_linear_equal_float (ei, f, data, vertical);
+ if (i != -2)
+ return i;
+ }
+
length = calc_length (data, ei->pos, vertical);
for (lp = 0; lp < length; lp++) {
Modified: trunk/src/mathfunc.c
==============================================================================
--- trunk/src/mathfunc.c (original)
+++ trunk/src/mathfunc.c Wed Apr 9 00:48:18 2008
@@ -7760,3 +7760,22 @@
#endif
/* ------------------------------------------------------------------------- */
+
+gint
+gnm_float_equal (gnm_float const *a, const gnm_float *b)
+{
+ return (*a == *b);
+}
+
+guint
+gnm_float_hash (gnm_float const *d)
+{
+ int expt;
+ gnm_float mant = gnm_frexp (gnm_abs (*d), &expt);
+ guint h = ((guint)(0x80000000u * mant)) ^ expt;
+ if (*d >= 0)
+ h ^= 0x55555555;
+ return h;
+}
+
+/* ------------------------------------------------------------------------- */
Modified: trunk/src/mathfunc.h
==============================================================================
--- trunk/src/mathfunc.h (original)
+++ trunk/src/mathfunc.h Wed Apr 9 00:48:18 2008
@@ -183,6 +183,9 @@
gnm_float permut (gnm_float n, gnm_float k);
gnm_float fact (int n);
+gint gnm_float_equal (gnm_float const *a, const gnm_float *b);
+guint gnm_float_hash (gnm_float const *d);
+
void mathfunc_init (void);
/* ------------------------------------------------------------------------- */
Modified: trunk/src/rangefunc.c
==============================================================================
--- trunk/src/rangefunc.c (original)
+++ trunk/src/rangefunc.c Wed Apr 9 00:48:18 2008
@@ -424,25 +424,6 @@
return 0;
}
-static guint
-float_hash (gnm_float const *d)
-{
- int expt;
- gnm_float mant = gnm_frexp (gnm_abs (*d), &expt);
- guint h = ((guint)(0x80000000u * mant)) ^ expt;
- if (*d >= 0)
- h ^= 0x55555555;
- return h;
-}
-
-static gint
-float_equal (gnm_float const *a, const gnm_float *b)
-{
- if (*a == *b)
- return 1;
- return 0;
-}
-
/* Most-common element. (The one whose first occurrence comes first in
case of several equally common. */
int
@@ -456,8 +437,8 @@
if (n <= 1) return 1;
- h = g_hash_table_new_full ((GHashFunc)float_hash,
- (GCompareFunc)float_equal,
+ h = g_hash_table_new_full ((GHashFunc)gnm_float_hash,
+ (GCompareFunc)gnm_float_equal,
NULL,
(GDestroyNotify)g_free);
for (i = 0; i < n; i++) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]