Commit d9e3a9f2 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-6089 - MySQL WL#7305 "Improve MDL scalability by using lock-free hash"

Extended lf-hash implementation to accept user defined hash function.
parent 9c8165fd
...@@ -143,6 +143,7 @@ struct st_lf_hash { ...@@ -143,6 +143,7 @@ struct st_lf_hash {
LF_ALLOCATOR alloc; /* allocator for elements */ LF_ALLOCATOR alloc; /* allocator for elements */
my_hash_get_key get_key; /* see HASH */ my_hash_get_key get_key; /* see HASH */
lf_hash_initializer initializer; /* called when an element is inserted */ lf_hash_initializer initializer; /* called when an element is inserted */
my_hash_function hash_function; /* see HASH */
CHARSET_INFO *charset; /* see HASH */ CHARSET_INFO *charset; /* see HASH */
uint key_offset, key_length; /* see HASH */ uint key_offset, key_length; /* see HASH */
uint element_size; /* size of memcpy'ed area on insert */ uint element_size; /* size of memcpy'ed area on insert */
......
...@@ -307,12 +307,13 @@ static inline const uchar* hash_key(const LF_HASH *hash, ...@@ -307,12 +307,13 @@ static inline const uchar* hash_key(const LF_HASH *hash,
@note, that the hash value is limited to 2^31, because we need one @note, that the hash value is limited to 2^31, because we need one
bit to distinguish between normal and dummy nodes. bit to distinguish between normal and dummy nodes.
*/ */
static inline uint calc_hash(LF_HASH *hash, const uchar *key, uint keylen) static inline my_hash_value_type calc_hash(const CHARSET_INFO *cs,
const uchar *key,
size_t keylen)
{ {
ulong nr1= 1, nr2= 4; ulong nr1= 1, nr2= 4;
hash->charset->coll->hash_sort(hash->charset, (uchar*) key, keylen, cs->coll->hash_sort(cs, (uchar*) key, keylen, &nr1, &nr2);
&nr1, &nr2); return nr1;
return nr1 & INT_MAX32;
} }
#define MAX_LOAD 1.0 /* average number of elements in a bucket */ #define MAX_LOAD 1.0 /* average number of elements in a bucket */
...@@ -356,6 +357,7 @@ void lf_hash_init(LF_HASH *hash, uint element_size, uint flags, ...@@ -356,6 +357,7 @@ void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
hash->key_length= key_length; hash->key_length= key_length;
hash->get_key= get_key; hash->get_key= get_key;
hash->initializer= default_initializer; hash->initializer= default_initializer;
hash->hash_function= calc_hash;
DBUG_ASSERT(get_key ? !key_offset && !key_length : key_length); DBUG_ASSERT(get_key ? !key_offset && !key_length : key_length);
} }
...@@ -403,7 +405,7 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) ...@@ -403,7 +405,7 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data)
return -1; return -1;
hash->initializer(hash, node + 1, data); hash->initializer(hash, node + 1, data);
node->key= hash_key(hash, (uchar *)(node+1), &node->keylen); node->key= hash_key(hash, (uchar *)(node+1), &node->keylen);
hashnr= calc_hash(hash, node->key, node->keylen); hashnr= hash->hash_function(hash->charset, node->key, node->keylen) & INT_MAX32;
bucket= hashnr % hash->size; bucket= hashnr % hash->size;
el= lf_dynarray_lvalue(&hash->array, bucket); el= lf_dynarray_lvalue(&hash->array, bucket);
if (unlikely(!el)) if (unlikely(!el))
...@@ -436,7 +438,9 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) ...@@ -436,7 +438,9 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data)
int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
{ {
LF_SLIST * volatile *el; LF_SLIST * volatile *el;
uint bucket, hashnr= calc_hash(hash, (uchar *)key, keylen); uint bucket, hashnr;
hashnr= hash->hash_function(hash->charset, (uchar *)key, keylen) & INT_MAX32;
/* hide OOM errors - if we cannot initalize a bucket, try the previous one */ /* hide OOM errors - if we cannot initalize a bucket, try the previous one */
for (bucket= hashnr % hash->size; ;bucket= my_clear_highest_bit(bucket)) for (bucket= hashnr % hash->size; ;bucket= my_clear_highest_bit(bucket))
...@@ -522,7 +526,9 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins, ...@@ -522,7 +526,9 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins,
void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
{ {
return lf_hash_search_using_hash_value(hash, pins, return lf_hash_search_using_hash_value(hash, pins,
calc_hash(hash, (uchar*) key, keylen), hash->hash_function(hash->charset,
(uchar*) key,
keylen) & INT_MAX32,
key, keylen); key, keylen);
} }
......
Markdown is supported
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