[gnumeric] VLOOKUP/HLOOKUP: fix problem when both are used on same range.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] VLOOKUP/HLOOKUP: fix problem when both are used on same range.
- Date: Thu, 27 Aug 2009 00:24:07 +0000 (UTC)
commit b247efbde9c96f3e0629952cdf2f861ef9a7ecac
Author: Morten Welinder <terra gnome org>
Date: Wed Aug 26 20:23:32 2009 -0400
VLOOKUP/HLOOKUP: fix problem when both are used on same range.
NEWS | 2 +
plugins/fn-lookup/ChangeLog | 7 ++
plugins/fn-lookup/functions.c | 166 ++++++++++++++++++++++++++++++++---------
3 files changed, 138 insertions(+), 37 deletions(-)
---
diff --git a/NEWS b/NEWS
index 6d36ade..b09ef54 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ Jean:
Morten:
* Add GAMMA.
* Fix Insert-Date+Time. [#592545]
+ * Fix problem with VLOOKUP and HLOOKUP when both are used on the
+ same data range. [#593238]
--------------------------------------------------------------------------
Gnumeric 1.9.10
diff --git a/plugins/fn-lookup/ChangeLog b/plugins/fn-lookup/ChangeLog
index ea7bdea..0998b9e 100644
--- a/plugins/fn-lookup/ChangeLog
+++ b/plugins/fn-lookup/ChangeLog
@@ -1,3 +1,10 @@
+2009-08-26 Morten Welinder <terra gnome org>
+
+ * functions.c (get_linear_lookup_cache,
+ get_bisection_lookup_cache): Take extra "vertical" argument and
+ separate caches for vertical and horizontal cases. All callers
+ changed. Fixes #593238.
+
2009-08-15 Morten Welinder <terra gnome org>
* Release 1.9.10
diff --git a/plugins/fn-lookup/functions.c b/plugins/fn-lookup/functions.c
index fc6ea7f..f046471 100644
--- a/plugins/fn-lookup/functions.c
+++ b/plugins/fn-lookup/functions.c
@@ -100,12 +100,18 @@ bisection_compare_float (const void *a_, const void *b_)
static GStringChunk *lookup_string_pool;
static GOMemChunk *lookup_float_pool;
-static GHashTable *linear_lookup_string_cache;
-static GHashTable *linear_lookup_float_cache;
-static GHashTable *linear_lookup_bool_cache;
-static GHashTable *bisection_lookup_string_cache;
-static GHashTable *bisection_lookup_float_cache;
-static GHashTable *bisection_lookup_bool_cache;
+static GHashTable *linear_hlookup_string_cache;
+static GHashTable *linear_hlookup_float_cache;
+static GHashTable *linear_hlookup_bool_cache;
+static GHashTable *linear_vlookup_string_cache;
+static GHashTable *linear_vlookup_float_cache;
+static GHashTable *linear_vlookup_bool_cache;
+static GHashTable *bisection_hlookup_string_cache;
+static GHashTable *bisection_hlookup_float_cache;
+static GHashTable *bisection_hlookup_bool_cache;
+static GHashTable *bisection_vlookup_string_cache;
+static GHashTable *bisection_vlookup_float_cache;
+static GHashTable *bisection_vlookup_bool_cache;
static size_t total_cache_size;
static void
@@ -116,23 +122,51 @@ clear_caches (void)
total_cache_size = 0;
- g_hash_table_destroy (linear_lookup_string_cache);
- linear_lookup_string_cache = NULL;
+ /* ---------- */
- g_hash_table_destroy (linear_lookup_float_cache);
- linear_lookup_float_cache = NULL;
+ g_hash_table_destroy (linear_hlookup_string_cache);
+ linear_hlookup_string_cache = NULL;
- g_hash_table_destroy (linear_lookup_bool_cache);
- linear_lookup_bool_cache = NULL;
+ g_hash_table_destroy (linear_hlookup_float_cache);
+ linear_hlookup_float_cache = NULL;
- g_hash_table_destroy (bisection_lookup_string_cache);
- bisection_lookup_string_cache = NULL;
+ g_hash_table_destroy (linear_hlookup_bool_cache);
+ linear_hlookup_bool_cache = NULL;
- g_hash_table_destroy (bisection_lookup_float_cache);
- bisection_lookup_float_cache = NULL;
+ /* ---------- */
- g_hash_table_destroy (bisection_lookup_bool_cache);
- bisection_lookup_bool_cache = NULL;
+ g_hash_table_destroy (linear_vlookup_string_cache);
+ linear_vlookup_string_cache = NULL;
+
+ g_hash_table_destroy (linear_vlookup_float_cache);
+ linear_vlookup_float_cache = NULL;
+
+ g_hash_table_destroy (linear_vlookup_bool_cache);
+ linear_vlookup_bool_cache = NULL;
+
+ /* ---------- */
+
+ g_hash_table_destroy (bisection_hlookup_string_cache);
+ bisection_hlookup_string_cache = NULL;
+
+ g_hash_table_destroy (bisection_hlookup_float_cache);
+ bisection_hlookup_float_cache = NULL;
+
+ g_hash_table_destroy (bisection_hlookup_bool_cache);
+ bisection_hlookup_bool_cache = NULL;
+
+ /* ---------- */
+
+ g_hash_table_destroy (bisection_vlookup_string_cache);
+ bisection_vlookup_string_cache = NULL;
+
+ g_hash_table_destroy (bisection_vlookup_float_cache);
+ bisection_vlookup_float_cache = NULL;
+
+ g_hash_table_destroy (bisection_vlookup_bool_cache);
+ bisection_vlookup_bool_cache = NULL;
+
+ /* ---------- */
g_string_chunk_free (lookup_string_pool);
lookup_string_pool = NULL;
@@ -156,38 +190,69 @@ create_caches (void)
sizeof (gnm_float),
sizeof (gnm_float) * 1000);
- linear_lookup_string_cache = g_hash_table_new_full
+ linear_hlookup_string_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)g_hash_table_destroy);
+ linear_hlookup_float_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)g_hash_table_destroy);
+ linear_hlookup_bool_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)g_hash_table_destroy);
+
+ linear_vlookup_string_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)g_hash_table_destroy);
- linear_lookup_float_cache = g_hash_table_new_full
+ linear_vlookup_float_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)g_hash_table_destroy);
- linear_lookup_bool_cache = g_hash_table_new_full
+ linear_vlookup_bool_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)g_hash_table_destroy);
- bisection_lookup_string_cache = g_hash_table_new_full
+ bisection_hlookup_string_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)lookup_bisection_cache_item_free);
- bisection_lookup_float_cache = g_hash_table_new_full
+ bisection_hlookup_float_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)lookup_bisection_cache_item_free);
- bisection_lookup_bool_cache = g_hash_table_new_full
+ bisection_hlookup_bool_cache = g_hash_table_new_full
((GHashFunc)value_hash,
(GEqualFunc)value_equal,
(GDestroyNotify)value_release,
(GDestroyNotify)lookup_bisection_cache_item_free);
+ bisection_vlookup_string_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)lookup_bisection_cache_item_free);
+ bisection_vlookup_float_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)lookup_bisection_cache_item_free);
+ bisection_vlookup_bool_cache = g_hash_table_new_full
+ ((GHashFunc)value_hash,
+ (GEqualFunc)value_equal,
+ (GDestroyNotify)value_release,
+ (GDestroyNotify)lookup_bisection_cache_item_free);
}
static void
@@ -204,7 +269,7 @@ prune_caches (void)
static GHashTable *
get_linear_lookup_cache (GnmFuncEvalInfo *ei,
GnmValue const *data, GnmValueType datatype,
- gboolean *brand_new)
+ gboolean vertical, gboolean *brand_new)
{
GnmValue const *key;
GnmValue *key_copy = NULL;
@@ -216,9 +281,21 @@ get_linear_lookup_cache (GnmFuncEvalInfo *ei,
/* The "&" here is for the pruning case. */
switch (datatype) {
- case VALUE_STRING: cache = &linear_lookup_string_cache; break;
- case VALUE_FLOAT: cache = &linear_lookup_float_cache; break;
- case VALUE_BOOLEAN: cache = &linear_lookup_bool_cache; break;
+ case VALUE_STRING:
+ cache = vertical
+ ? &linear_vlookup_string_cache
+ : &linear_hlookup_string_cache;
+ break;
+ case VALUE_FLOAT:
+ cache = vertical
+ ? &linear_vlookup_float_cache
+ : &linear_hlookup_float_cache;
+ break;
+ case VALUE_BOOLEAN:
+ cache = vertical
+ ? &linear_vlookup_bool_cache
+ : &linear_hlookup_bool_cache;
+ break;
default:
g_assert_not_reached ();
return NULL;
@@ -264,7 +341,7 @@ get_linear_lookup_cache (GnmFuncEvalInfo *ei,
static LookupBisectionCacheItem *
get_bisection_lookup_cache (GnmFuncEvalInfo *ei,
GnmValue const *data, GnmValueType datatype,
- gboolean *brand_new)
+ gboolean vertical, gboolean *brand_new)
{
GnmValue const *key;
GnmValue *key_copy = NULL;
@@ -277,9 +354,21 @@ get_bisection_lookup_cache (GnmFuncEvalInfo *ei,
/* The "&" here is for the pruning case. */
switch (datatype) {
- case VALUE_STRING: cache = &bisection_lookup_string_cache; break;
- case VALUE_FLOAT: cache = &bisection_lookup_float_cache; break;
- case VALUE_BOOLEAN: cache = &bisection_lookup_bool_cache; break;
+ case VALUE_STRING:
+ cache = vertical
+ ? &bisection_vlookup_string_cache
+ : &bisection_hlookup_string_cache;
+ break;
+ case VALUE_FLOAT:
+ cache = vertical
+ ? &bisection_vlookup_float_cache
+ : &bisection_hlookup_float_cache;
+ break;
+ case VALUE_BOOLEAN:
+ cache = vertical
+ ? &bisection_vlookup_bool_cache
+ : &bisection_hlookup_bool_cache;
+ break;
default:
g_assert_not_reached ();
return NULL;
@@ -377,7 +466,8 @@ find_index_linear_equal_string (GnmFuncEvalInfo *ei,
char *sc;
gboolean found, brand_new;
- h = get_linear_lookup_cache (ei, data, VALUE_STRING, &brand_new);
+ h = get_linear_lookup_cache (ei, data, VALUE_STRING, vertical,
+ &brand_new);
if (!h)
return LOOKUP_DATA_ERROR;
@@ -420,7 +510,8 @@ find_index_linear_equal_float (GnmFuncEvalInfo *ei,
gboolean found, brand_new;
/* This handles floats and bools, but with separate caches. */
- h = get_linear_lookup_cache (ei, data, find->type, &brand_new);
+ h = get_linear_lookup_cache (ei, data, find->type, vertical,
+ &brand_new);
if (!h)
return LOOKUP_DATA_ERROR;
@@ -506,7 +597,8 @@ find_index_bisection (GnmFuncEvalInfo *ei,
int (*comparer) (const void *,const void *);
LookupBisectionCacheItemElem key;
- bc = get_bisection_lookup_cache (ei, data, find->type, &brand_new);
+ bc = get_bisection_lookup_cache (ei, data, find->type, vertical,
+ &brand_new);
if (!bc)
return LOOKUP_DATA_ERROR;
@@ -821,7 +913,7 @@ static GnmFuncHelp const help_vlookup[] = {
{ GNM_FUNC_HELP_ARG, F_("range:range to search")},
{ GNM_FUNC_HELP_ARG, F_("column:1-based column offset indicating the return values")},
{ GNM_FUNC_HELP_ARG, F_("approximate:if false, an exact match of @{value} "
- "must be found; defaults to FALSE")},
+ "must be found; defaults to TRUE")},
{ GNM_FUNC_HELP_ARG, F_("as_index:if true, the 0-based row offset is "
"returned; defaults to FALSE")},
{ GNM_FUNC_HELP_DESCRIPTION, F_("VLOOKUP function finds the row in @{range} that has a first "
@@ -882,7 +974,7 @@ static GnmFuncHelp const help_hlookup[] = {
{ GNM_FUNC_HELP_ARG, F_("range:range to search")},
{ GNM_FUNC_HELP_ARG, F_("row:1-based column offset indicating the return values ")},
{ GNM_FUNC_HELP_ARG, F_("approximate:if false, an exact match of @{value} "
- "must be found; defaults to FALSE")},
+ "must be found; defaults to TRUE")},
{ GNM_FUNC_HELP_ARG, F_("as_index:if true, the 0-based row offset is "
"returned; defaults to FALSE")},
{ GNM_FUNC_HELP_DESCRIPTION, F_("HLOOKUP function finds the row in @{range} that has a first "
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]