summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Ronstrom <mikael@mysql.com>2009-10-09 14:22:22 +0200
committerMikael Ronstrom <mikael@mysql.com>2009-10-09 14:22:22 +0200
commitd3540b216f2d39126d77985db3f7639eb45bf967 (patch)
treebd91284ce826b8e44b1a50008e69d8dc56a5d5a1
parentee696e4163354b85c60c68cb791005fa127abcea (diff)
downloadmariadb-git-d3540b216f2d39126d77985db3f7639eb45bf967.tar.gz
A minor change to MySQL's hash where calculation of hash can be done separately to avoid doing it under contended mutex locks
-rw-r--r--include/hash.h9
-rw-r--r--mysys/hash.c29
-rw-r--r--sql/sql_base.cc9
3 files changed, 43 insertions, 4 deletions
diff --git a/include/hash.h b/include/hash.h
index 629b404e8a7..b6fc365ab76 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -45,6 +45,7 @@ extern "C" {
#define hash_element my_hash_element
#define hash_search my_hash_search
#define hash_first my_hash_first
+#define hash_first_from_hash_value my_hash_first_from_hash_value
#define hash_next my_hash_next
#define hash_insert my_hash_insert
#define hash_delete my_hash_delete
@@ -94,8 +95,16 @@ void my_hash_free(HASH *tree);
void my_hash_reset(HASH *hash);
uchar *my_hash_element(HASH *hash, ulong idx);
uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
+uchar *my_hash_search_using_hash_value(const HASH *info, uint hash_value,
+ const uchar *key, size_t length);
+uint my_calc_hash(const HASH *info, const uchar *key, size_t length);
uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state);
+uchar *my_hash_first_from_hash_value(const HASH *info,
+ uint hash_value,
+ const uchar *key,
+ size_t length,
+ HASH_SEARCH_STATE *state);
uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info, const uchar *data);
diff --git a/mysys/hash.c b/mysys/hash.c
index 63933abb085..367ac8713dd 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -214,6 +214,20 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
return my_hash_first(hash, key, length, &state);
}
+uchar* my_hash_search_using_hash_value(const HASH *hash,
+ uint hash_value,
+ const uchar *key,
+ size_t length)
+{
+ HASH_SEARCH_STATE state;
+ return my_hash_first_from_hash_value(hash, hash_value,
+ key, length, &state);
+}
+
+uint my_calc_hash(const HASH *hash, const uchar *key, size_t length)
+{
+ return calc_hash(hash, key, length ? length : hash->key_length);
+}
/*
Search after a record based on a key
@@ -224,14 +238,25 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
HASH_SEARCH_STATE *current_record)
{
+ return my_hash_first_from_hash_value(hash,
+ calc_hash(hash, key, length ? length : hash->key_length),
+ key, length, current_record);
+}
+
+uchar* my_hash_first_from_hash_value(const HASH *hash,
+ uint hash_value,
+ const uchar *key,
+ size_t length,
+ HASH_SEARCH_STATE *current_record)
+{
HASH_LINK *pos;
uint flag,idx;
- DBUG_ENTER("my_hash_first");
+ DBUG_ENTER("my_hash_first_from_hash_value");
flag=1;
if (hash->records)
{
- idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length),
+ idx= my_hash_mask(hash_value,
hash->blength, hash->records);
do
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b81070000b3..064d277e0b4 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2513,6 +2513,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
char key[MAX_DBKEY_LENGTH];
uint key_length;
char *alias= table_list->alias;
+ uint hash_value;
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
@@ -2702,6 +2703,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
on disk.
*/
+ hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length);
VOID(pthread_mutex_lock(&LOCK_open));
/*
@@ -2744,8 +2746,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
an implicit "pending locks queue" - see
wait_for_locked_table_names for details.
*/
- for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length,
- &state);
+ for (table= (TABLE*) hash_first_from_hash_value(&open_cache,
+ hash_value,
+ (uchar*) key,
+ key_length,
+ &state);
table && table->in_use ;
table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length,
&state))