Commit 3aab2c6e authored by Hans-Nikolai Viessmann's avatar Hans-Nikolai Viessmann Committed by Reg Huijben
Browse files

memoize last used key on search next

In the case where we have multiple keys stored in the same bucket,
a next search for the second (or later) key leads to a bogus lookup.
This occurs as the key is not memoized between consecutive calls
of the next function, and so conflicts with some state information
about the LUT. This commit resolves this issue, and improves the unit
tests to specifically look for this case.
parent e826a756
......@@ -402,7 +402,7 @@ ComputeHashStat (lut_t *lut, char *note, hash_key_t min_key, hash_key_t max_key)
******************************************************************************/
static void **
SearchInLUT_ (lut_size_t size, lut_size_t *i, void **entry, void *old_item,
SearchInLUT_ (lut_size_t size, lut_size_t *i, void ***entry, void *old_item,
hash_key_t hash_key, is_equal_fun_t is_equal_fun, char *old_format,
char *new_format)
{
......@@ -412,14 +412,14 @@ SearchInLUT_ (lut_size_t size, lut_size_t *i, void **entry, void *old_item,
/* search in the collision table for 'old_item' */
for (; (*i) < size; (*i)++) {
if (is_equal_fun (entry[0], old_item)) {
new_item_p = entry + 1;
if (is_equal_fun ((*entry)[0], old_item)) {
new_item_p = (*entry) + 1;
break;
}
entry += 2;
(*entry) += 2;
if (((*i) + 1) % (LUT_SIZE) == 0) {
/* last table entry is reached -> enter next table of the chain */
entry = (void **)*entry;
(*entry) = (void **)*(*entry);
}
}
......@@ -456,15 +456,19 @@ SearchInLUT (lut_t *lut, void *old_item, hash_key_t hash_key, is_equal_fun_t is_
char *old_format, char *new_format)
{
void **new_item_p = NULL;
void **entry = NULL;
lut_size_t i = 0;
DBUG_ENTER ();
entry = lut[hash_key].first;
DBUG_PRINT ("> lut (" F_PTR ")", (void *)lut);
if (lut != NULL) {
if (old_item != NULL) {
new_item_p
= SearchInLUT_ (lut[hash_key].size, &i, lut[hash_key].first, old_item,
= SearchInLUT_ (lut[hash_key].size, &i, &entry, old_item,
hash_key, is_equal_fun, old_format, new_format);
DBUG_PRINT ("< finished");
......@@ -526,7 +530,7 @@ SearchInLUT_state (lut_t *lut, void *old_item, hash_key_t hash_key,
store_entry = store_lut[hash_key].first;
new_item_p
= SearchInLUT_ (store_size, &store_i, store_entry, store_old_item,
= SearchInLUT_ (store_size, &store_i, &store_entry, store_old_item,
hash_key, is_equal_fun, old_format, new_format);
DBUG_PRINT ("< finished");
......@@ -552,7 +556,7 @@ SearchInLUT_state (lut_t *lut, void *old_item, hash_key_t hash_key,
store_i++;
new_item_p
= SearchInLUT_ (store_size, &store_i, store_entry, store_old_item,
= SearchInLUT_ (store_size, &store_i, &store_entry, store_old_item,
store_hash_key, is_equal_fun, old_format, new_format);
DBUG_PRINT ("< finished");
......
......@@ -244,52 +244,118 @@ TEST_F (LUTTest, InsertAndUpdateS)
TEST_F (LUTTest, SearchP)
{
void *key = (void*)'a';
void *v1 = (void*)'b';
void *v2 = (void*)'c';
void *v3 = (void*)'d';
char *str = const_cast<char*>("abcdefgh");
void *akey = &str[0];
void *bkey = &str[1];
void *v1 = &str[2];
void *v2 = &str[3];
void *v3 = &str[4];
void *v4 = &str[5];
void *v5 = &str[6];
void *v6 = &str[7];
void *ret;
void **res;
res = LUTsearchInLutP (lut_1, key);
res = LUTsearchInLutP (lut_1, akey);
ASSERT_FALSE (res);
lut_1 = LUTinsertIntoLutP (lut_1, key, v1);
lut_1 = LUTinsertIntoLutP (lut_1, key, v2);
lut_1 = LUTinsertIntoLutP (lut_1, key, v3);
res = LUTsearchInLutP (lut_1, bkey);
ASSERT_FALSE (res);
lut_1 = LUTinsertIntoLutP (lut_1, akey, v1);
lut_1 = LUTinsertIntoLutP (lut_1, akey, v2);
lut_1 = LUTinsertIntoLutP (lut_1, akey, v3);
lut_1 = LUTinsertIntoLutP (lut_1, bkey, v4);
lut_1 = LUTinsertIntoLutP (lut_1, bkey, v5);
lut_1 = LUTinsertIntoLutP (lut_1, bkey, v6);
ASSERT_FALSE (LUTisEmptyLut (lut_1));
res = LUTsearchInLutP (lut_1, key);
res = LUTsearchInLutP (lut_1, akey);
ASSERT_TRUE (res);
ASSERT_EQ (*res, v1);
ret = LUTsearchInLutPp (lut_1, key);
ret = LUTsearchInLutPp (lut_1, akey);
ASSERT_TRUE (ret);
ASSERT_EQ (ret, v1);
res = LUTsearchInLutNextP ();
ASSERT_TRUE (res);
ASSERT_EQ (*res, v2);
ASSERT_NE (*res, v3);
res = LUTsearchInLutNextP ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v2);
ASSERT_EQ (*res, v3);
res = LUTsearchInLutP (lut_1, bkey);
ASSERT_TRUE (res);
ASSERT_EQ (*res, v4);
res = LUTsearchInLutNextP ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v4);
ASSERT_EQ (*res, v5);
res = LUTsearchInLutNextP ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v5);
ASSERT_EQ (*res, v6);
}
TEST_F (LUTTest, SearchS)
{
char *key = const_cast<char*>("a");
void *v1 = (void*)'b';
void *v2 = (void*)'c';
void *v3 = (void*)'d';
char *akey = const_cast<char*>("a");
char *bkey = const_cast<char*>("b");
void *v1 = const_cast<char*>("c");
void *v2 = const_cast<char*>("d");
void *v3 = const_cast<char*>("e");
void *v4 = const_cast<char*>("f");
void *v5 = const_cast<char*>("g");
void *v6 = const_cast<char*>("h");
void *ret;
void **res;
res = LUTsearchInLutS (lut_1, key);
res = LUTsearchInLutS (lut_1, akey);
ASSERT_FALSE (res);
lut_1 = LUTinsertIntoLutS (lut_1, key, v1);
lut_1 = LUTinsertIntoLutS (lut_1, key, v2);
lut_1 = LUTinsertIntoLutS (lut_1, key, v3);
lut_1 = LUTinsertIntoLutS (lut_1, akey, v1);
lut_1 = LUTinsertIntoLutS (lut_1, akey, v2);
lut_1 = LUTinsertIntoLutS (lut_1, akey, v3);
lut_1 = LUTinsertIntoLutS (lut_1, bkey, v4);
lut_1 = LUTinsertIntoLutS (lut_1, bkey, v5);
lut_1 = LUTinsertIntoLutS (lut_1, bkey, v6);
ASSERT_FALSE (LUTisEmptyLut (lut_1));
res = LUTsearchInLutS (lut_1, key);
res = LUTsearchInLutS (lut_1, akey);
ASSERT_TRUE (res);
ASSERT_EQ (*res, v1);
ret = LUTsearchInLutSs (lut_1, key);
ret = LUTsearchInLutSs (lut_1, akey);
ASSERT_TRUE (ret);
ASSERT_EQ (ret, v1);
res = LUTsearchInLutNextS ();
ASSERT_TRUE (res);
ASSERT_EQ (*res, v2);
ASSERT_NE (*res, v3);
res = LUTsearchInLutNextS ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v2);
ASSERT_EQ (*res, v3);
res = LUTsearchInLutS (lut_1, bkey);
ASSERT_TRUE (res);
ASSERT_EQ (*res, v4);
res = LUTsearchInLutNextS ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v4);
ASSERT_EQ (*res, v5);
res = LUTsearchInLutNextS ();
ASSERT_TRUE (res);
ASSERT_NE (*res, v5);
ASSERT_EQ (*res, v6);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment