From b95c8ce530cbbd92b232324dc2c4376615bd1b5d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 6 Mar 2014 16:19:12 +0400 Subject: 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 --- sql/mdl.cc | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'sql/mdl.cc') 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) -- cgit v1.2.1