mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Merge WL#5137 to mysql-next-mr
This commit is contained in:
@@ -30,6 +30,7 @@ extern "C" {
|
|||||||
/* flags for hash_init */
|
/* flags for hash_init */
|
||||||
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
|
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
|
||||||
|
|
||||||
|
typedef uint my_hash_value_type;
|
||||||
typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
|
typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
|
||||||
typedef void (*my_hash_free_key)(void *);
|
typedef void (*my_hash_free_key)(void *);
|
||||||
|
|
||||||
@@ -60,8 +61,18 @@ void my_hash_free(HASH *tree);
|
|||||||
void my_hash_reset(HASH *hash);
|
void my_hash_reset(HASH *hash);
|
||||||
uchar *my_hash_element(HASH *hash, ulong idx);
|
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(const HASH *info, const uchar *key, size_t length);
|
||||||
|
uchar *my_hash_search_using_hash_value(const HASH *info,
|
||||||
|
my_hash_value_type hash_value,
|
||||||
|
const uchar *key, size_t length);
|
||||||
|
my_hash_value_type 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,
|
uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
|
||||||
HASH_SEARCH_STATE *state);
|
HASH_SEARCH_STATE *state);
|
||||||
|
uchar *my_hash_first_from_hash_value(const HASH *info,
|
||||||
|
my_hash_value_type 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,
|
uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
|
||||||
HASH_SEARCH_STATE *state);
|
HASH_SEARCH_STATE *state);
|
||||||
my_bool my_hash_insert(HASH *info, const uchar *data);
|
my_bool my_hash_insert(HASH *info, const uchar *data);
|
||||||
|
49
mysys/hash.c
49
mysys/hash.c
@@ -33,16 +33,18 @@ typedef struct st_hash_info {
|
|||||||
uchar *data; /* data for current entry */
|
uchar *data; /* data for current entry */
|
||||||
} HASH_LINK;
|
} HASH_LINK;
|
||||||
|
|
||||||
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength);
|
static uint my_hash_mask(my_hash_value_type hashnr,
|
||||||
|
size_t buffmax, size_t maxlength);
|
||||||
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
|
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
|
||||||
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
|
static my_hash_value_type calc_hash(const HASH *hash,
|
||||||
|
const uchar *key, size_t length)
|
||||||
{
|
{
|
||||||
ulong nr1=1, nr2=4;
|
ulong nr1=1, nr2=4;
|
||||||
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
|
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
|
||||||
return nr1;
|
return (my_hash_value_type)nr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,7 +181,8 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length,
|
|||||||
|
|
||||||
/* Calculate pos according to keys */
|
/* Calculate pos according to keys */
|
||||||
|
|
||||||
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength)
|
static uint my_hash_mask(my_hash_value_type hashnr, size_t buffmax,
|
||||||
|
size_t maxlength)
|
||||||
{
|
{
|
||||||
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
||||||
return (hashnr & ((buffmax >> 1) -1));
|
return (hashnr & ((buffmax >> 1) -1));
|
||||||
@@ -200,7 +203,7 @@ static
|
|||||||
#if !defined(__USLC__) && !defined(__sgi)
|
#if !defined(__USLC__) && !defined(__sgi)
|
||||||
inline
|
inline
|
||||||
#endif
|
#endif
|
||||||
unsigned int rec_hashnr(HASH *hash,const uchar *record)
|
my_hash_value_type rec_hashnr(HASH *hash,const uchar *record)
|
||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
|
uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
|
||||||
@@ -214,6 +217,21 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
|
|||||||
return my_hash_first(hash, key, length, &state);
|
return my_hash_first(hash, key, length, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uchar* my_hash_search_using_hash_value(const HASH *hash,
|
||||||
|
my_hash_value_type 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
my_hash_value_type 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
|
Search after a record based on a key
|
||||||
|
|
||||||
@@ -223,15 +241,26 @@ 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,
|
uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
|
||||||
HASH_SEARCH_STATE *current_record)
|
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,
|
||||||
|
my_hash_value_type hash_value,
|
||||||
|
const uchar *key,
|
||||||
|
size_t length,
|
||||||
|
HASH_SEARCH_STATE *current_record)
|
||||||
{
|
{
|
||||||
HASH_LINK *pos;
|
HASH_LINK *pos;
|
||||||
uint flag,idx;
|
uint flag,idx;
|
||||||
DBUG_ENTER("my_hash_first");
|
DBUG_ENTER("my_hash_first_from_hash_value");
|
||||||
|
|
||||||
flag=1;
|
flag=1;
|
||||||
if (hash->records)
|
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);
|
hash->blength, hash->records);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -331,7 +360,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
|||||||
my_bool my_hash_insert(HASH *info, const uchar *record)
|
my_bool my_hash_insert(HASH *info, const uchar *record)
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
size_t idx,halfbuff,hash_nr,first_index;
|
size_t idx,halfbuff,first_index;
|
||||||
|
my_hash_value_type hash_nr;
|
||||||
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
|
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
|
||||||
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
|
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
|
||||||
|
|
||||||
@@ -467,7 +497,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
|
|||||||
|
|
||||||
my_bool my_hash_delete(HASH *hash, uchar *record)
|
my_bool my_hash_delete(HASH *hash, uchar *record)
|
||||||
{
|
{
|
||||||
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
|
uint blength,pos2,idx,empty_index;
|
||||||
|
my_hash_value_type pos_hashnr, lastpos_hashnr;
|
||||||
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
|
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
|
||||||
DBUG_ENTER("my_hash_delete");
|
DBUG_ENTER("my_hash_delete");
|
||||||
if (!hash->records)
|
if (!hash->records)
|
||||||
|
@@ -2551,6 +2551,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_DBKEY_LENGTH];
|
||||||
uint key_length;
|
uint key_length;
|
||||||
char *alias= table_list->alias;
|
char *alias= table_list->alias;
|
||||||
|
my_hash_value_type hash_value;
|
||||||
HASH_SEARCH_STATE state;
|
HASH_SEARCH_STATE state;
|
||||||
DBUG_ENTER("open_table");
|
DBUG_ENTER("open_table");
|
||||||
|
|
||||||
@@ -2740,6 +2741,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
on disk.
|
on disk.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length);
|
||||||
pthread_mutex_lock(&LOCK_open);
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2782,8 +2784,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
an implicit "pending locks queue" - see
|
an implicit "pending locks queue" - see
|
||||||
wait_for_locked_table_names for details.
|
wait_for_locked_table_names for details.
|
||||||
*/
|
*/
|
||||||
for (table= (TABLE*) my_hash_first(&open_cache, (uchar*) key, key_length,
|
for (table= (TABLE*) my_hash_first_from_hash_value(&open_cache,
|
||||||
&state);
|
hash_value,
|
||||||
|
(uchar*) key,
|
||||||
|
key_length,
|
||||||
|
&state);
|
||||||
table && table->in_use ;
|
table && table->in_use ;
|
||||||
table= (TABLE*) my_hash_next(&open_cache, (uchar*) key, key_length,
|
table= (TABLE*) my_hash_next(&open_cache, (uchar*) key, key_length,
|
||||||
&state))
|
&state))
|
||||||
|
Reference in New Issue
Block a user