summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2014-03-06 16:19:12 +0400
committerSergey Vojtovich <svoj@mariadb.org>2014-03-06 16:19:12 +0400
commitb95c8ce530cbbd92b232324dc2c4376615bd1b5d (patch)
tree60222ef1542c97949e24dcbc4474f5484b86119b /sql
parentae87e63184a451cd0c9cf95f11f51b78bb40fbc3 (diff)
downloadmariadb-git-b95c8ce530cbbd92b232324dc2c4376615bd1b5d.tar.gz
MDEV-5675 - Performance: my_hash_sort_bin is called too often
Reduced number of my_hash_sort_bin() calls from 4 to 1 per query. Reduced number of memory accesses done by my_hash_sort_bin(). Details: - let MDL subsystem use pre-calculated hash value for hash inserts and deletes - let table cache use pre-calculated MDL hash value - MDL namespace is excluded from hash value calculation, so that hash value can be used by table cache as is - hash value for MDL is calculated as resulting hash value + MDL namespace - extended hash implementation to accept user defined hash function
Diffstat (limited to 'sql')
-rw-r--r--sql/mdl.cc42
-rw-r--r--sql/mdl.h15
-rw-r--r--sql/sql_acl.cc10
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/table_cache.cc6
-rw-r--r--sql/table_cache.h8
6 files changed, 51 insertions, 34 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc
index d8aa6e1d1b4..ce2483a8d8c 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -124,15 +124,9 @@ class MDL_map_partition
public:
MDL_map_partition();
~MDL_map_partition();
- inline MDL_lock *find_or_insert(const MDL_key *mdl_key,
- my_hash_value_type hash_value);
- unsigned long get_lock_owner(const MDL_key *key,
- my_hash_value_type hash_value);
+ inline MDL_lock *find_or_insert(const MDL_key *mdl_key);
+ unsigned long get_lock_owner(const MDL_key *key);
inline void remove(MDL_lock *lock);
- my_hash_value_type get_key_hash(const MDL_key *mdl_key) const
- {
- return my_calc_hash(&m_locks, mdl_key->ptr(), mdl_key->length());
- }
private:
bool move_from_hash_to_lock_mutex(MDL_lock *lock);
/** A partition of all acquired locks in the server. */
@@ -766,13 +760,21 @@ void MDL_map::init()
}
+my_hash_value_type mdl_hash_function(const CHARSET_INFO *cs,
+ const uchar *key, size_t length)
+{
+ MDL_key *mdl_key= (MDL_key*) (key - offsetof(MDL_key, m_ptr));
+ return mdl_key->hash_value();
+}
+
+
/** Initialize the partition in the container with all MDL locks. */
MDL_map_partition::MDL_map_partition()
{
mysql_mutex_init(key_MDL_map_mutex, &m_mutex, NULL);
- my_hash_init(&m_locks, &my_charset_bin, 16 /* FIXME */, 0, 0,
- mdl_locks_key, 0, 0);
+ my_hash_init2(&m_locks, 0, &my_charset_bin, 16 /* FIXME */, 0, 0,
+ mdl_locks_key, mdl_hash_function, 0, 0);
};
@@ -846,11 +848,10 @@ MDL_lock* MDL_map::find_or_insert(const MDL_key *mdl_key)
return lock;
}
- my_hash_value_type hash_value= m_partitions.at(0)->get_key_hash(mdl_key);
- uint part_id= hash_value % mdl_locks_hash_partitions;
+ uint part_id= mdl_key->hash_value() % mdl_locks_hash_partitions;
MDL_map_partition *part= m_partitions.at(part_id);
- return part->find_or_insert(mdl_key, hash_value);
+ return part->find_or_insert(mdl_key);
}
@@ -863,15 +864,14 @@ MDL_lock* MDL_map::find_or_insert(const MDL_key *mdl_key)
@retval NULL - Failure (OOM).
*/
-MDL_lock* MDL_map_partition::find_or_insert(const MDL_key *mdl_key,
- my_hash_value_type hash_value)
+MDL_lock* MDL_map_partition::find_or_insert(const MDL_key *mdl_key)
{
MDL_lock *lock;
retry:
mysql_mutex_lock(&m_mutex);
if (!(lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks,
- hash_value,
+ mdl_key->hash_value(),
mdl_key->ptr(),
mdl_key->length())))
{
@@ -1023,10 +1023,9 @@ MDL_map::get_lock_owner(const MDL_key *mdl_key)
}
else
{
- my_hash_value_type hash_value= m_partitions.at(0)->get_key_hash(mdl_key);
- uint part_id= hash_value % mdl_locks_hash_partitions;
+ uint part_id= mdl_key->hash_value() % mdl_locks_hash_partitions;
MDL_map_partition *part= m_partitions.at(part_id);
- res= part->get_lock_owner(mdl_key, hash_value);
+ res= part->get_lock_owner(mdl_key);
}
return res;
}
@@ -1034,15 +1033,14 @@ MDL_map::get_lock_owner(const MDL_key *mdl_key)
unsigned long
-MDL_map_partition::get_lock_owner(const MDL_key *mdl_key,
- my_hash_value_type hash_value)
+MDL_map_partition::get_lock_owner(const MDL_key *mdl_key)
{
MDL_lock *lock;
unsigned long res= 0;
mysql_mutex_lock(&m_mutex);
lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks,
- hash_value,
+ mdl_key->hash_value(),
mdl_key->ptr(),
mdl_key->length());
if (lock)
diff --git a/sql/mdl.h b/sql/mdl.h
index c7c445c75e1..6f31b46f17f 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -28,6 +28,7 @@
#include <my_sys.h>
#include <m_string.h>
#include <mysql_com.h>
+#include <hash.h>
#include <algorithm>
@@ -347,12 +348,15 @@ public:
m_ptr - 1);
m_length= static_cast<uint16>(strmake(m_ptr + m_db_name_length + 2, name,
NAME_LEN) - m_ptr + 1);
+ m_hash_value= my_hash_sort(&my_charset_bin, (uchar*) m_ptr + 1,
+ m_length - 1);
}
void mdl_key_init(const MDL_key *rhs)
{
memcpy(m_ptr, rhs->m_ptr, rhs->m_length);
m_length= rhs->m_length;
m_db_name_length= rhs->m_db_name_length;
+ m_hash_value= rhs->m_hash_value;
}
bool is_equal(const MDL_key *rhs) const
{
@@ -392,15 +396,26 @@ public:
{
return & m_namespace_to_wait_state_name[(int)mdl_namespace()];
}
+ my_hash_value_type hash_value() const
+ {
+ return m_hash_value + mdl_namespace();
+ }
+ my_hash_value_type tc_hash_value() const
+ {
+ return m_hash_value;
+ }
private:
uint16 m_length;
uint16 m_db_name_length;
+ my_hash_value_type m_hash_value;
char m_ptr[MAX_MDLKEY_LENGTH];
static PSI_stage_info m_namespace_to_wait_state_name[NAMESPACE_END];
private:
MDL_key(const MDL_key &); /* not implemented */
MDL_key &operator=(const MDL_key &); /* not implemented */
+ friend my_hash_value_type mdl_hash_function(const CHARSET_INFO *,
+ const uchar *, size_t);
};
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index fdb32233d92..8d9989cd748 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1085,7 +1085,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
table->use_all_columns();
(void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER), 50, 100, MYF(0));
(void) my_hash_init2(&acl_roles,50, &my_charset_utf8_bin,
- 0,0,0, (my_hash_get_key) acl_role_get_key,
+ 0, 0, 0, (my_hash_get_key) acl_role_get_key, 0,
(void (*)(void *))free_acl_role, 0);
username_char_length= MY_MIN(table->field[1]->char_length(),
@@ -1427,8 +1427,8 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
table->use_all_columns();
/* account for every role mapping */
- (void) my_hash_init2(&acl_roles_mappings, 50, system_charset_info,
- 0,0,0, (my_hash_get_key) acl_role_map_get_key, 0,0);
+ (void) my_hash_init2(&acl_roles_mappings, 50, system_charset_info, 0, 0, 0,
+ (my_hash_get_key) acl_role_map_get_key, 0, 0, 0);
MEM_ROOT temp_root;
init_alloc_root(&temp_root, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
while (!(read_record_info.read_record(&read_record_info)))
@@ -3734,8 +3734,8 @@ public:
bool ok() { return privs != 0 || cols != 0; }
void init_hash()
{
- my_hash_init2(&hash_columns, 4, system_charset_info,
- 0, 0, 0, (my_hash_get_key) get_key_column, 0, 0);
+ my_hash_init2(&hash_columns, 4, system_charset_info, 0, 0, 0,
+ (my_hash_get_key) get_key_column, 0, 0, 0);
}
};
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8cfb7850ae3..82f98e0604b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2296,7 +2296,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
retry_share:
share= tdc_acquire_share(thd, table_list->db, table_list->table_name,
- key, key_length, gts_flags, &table);
+ key, key_length,
+ table_list->mdl_request.key.tc_hash_value(),
+ gts_flags, &table);
if (!share)
{
diff --git a/sql/table_cache.cc b/sql/table_cache.cc
index ac6621226ef..fbafd8e0c9f 100644
--- a/sql/table_cache.cc
+++ b/sql/table_cache.cc
@@ -664,16 +664,14 @@ void tdc_unlock_share(TABLE_SHARE *share)
*/
TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, const char *table_name,
- const char *key, uint key_length, uint flags,
+ const char *key, uint key_length,
+ my_hash_value_type hash_value, uint flags,
TABLE **out_table)
{
TABLE_SHARE *share;
bool was_unused;
- my_hash_value_type hash_value;
DBUG_ENTER("tdc_acquire_share");
- hash_value= my_calc_hash(&tdc_hash, (uchar*) key, key_length);
-
mysql_rwlock_rdlock(&LOCK_tdc);
share= (TABLE_SHARE*) my_hash_search_using_hash_value(&tdc_hash, hash_value,
(uchar*) key,
diff --git a/sql/table_cache.h b/sql/table_cache.h
index a30a07b8357..6da6a667792 100644
--- a/sql/table_cache.h
+++ b/sql/table_cache.h
@@ -40,6 +40,7 @@ extern void tdc_unlock_share(TABLE_SHARE *share);
extern TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db,
const char *table_name,
const char *key, uint key_length,
+ my_hash_value_type hash_value,
uint flags, TABLE **out_table);
extern void tdc_release_share(TABLE_SHARE *share);
extern bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
@@ -88,7 +89,9 @@ static inline TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db,
const char *key,
uint key_length, uint flags)
{
- return tdc_acquire_share(thd, db, table_name, key, key_length, flags, 0);
+ return tdc_acquire_share(thd, db, table_name, key, key_length,
+ my_hash_sort(&my_charset_bin, (uchar*) key,
+ key_length), flags, 0);
}
@@ -120,7 +123,8 @@ static inline TABLE_SHARE *tdc_acquire_share_shortlived(THD *thd, TABLE_LIST *tl
{
const char *key;
uint key_length= get_table_def_key(tl, &key);
- return tdc_acquire_share(thd, tl->db, tl->table_name, key, key_length, flags);
+ return tdc_acquire_share(thd, tl->db, tl->table_name, key, key_length,
+ tl->mdl_request.key.tc_hash_value(), flags, 0);
}