Hash now supports several charsets

parent f8a54528
...@@ -2325,7 +2325,8 @@ static void var_from_env(const char* name, const char* def_val) ...@@ -2325,7 +2325,8 @@ static void var_from_env(const char* name, const char* def_val)
static void init_var_hash() static void init_var_hash()
{ {
VAR* v; VAR* v;
if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0))) if (hash_init(&var_hash, system_charset_info,
1024, 0, 0, get_var_key, var_free, MYF(0)))
die("Variable hash initialization failed"); die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306"); var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307"); var_from_env("SLAVE_MYPORT", "9307");
......
...@@ -40,10 +40,12 @@ typedef struct st_hash { ...@@ -40,10 +40,12 @@ typedef struct st_hash {
DYNAMIC_ARRAY array; /* Place for hash_keys */ DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key; hash_get_key get_key;
void (*free)(void *); void (*free)(void *);
uint (*calc_hashnr)(const byte *key,uint length); uint (*calc_hashnr)(CHARSET_INFO *cs, const byte *key,uint length);
CHARSET_INFO *charset;
} HASH; } HASH;
my_bool hash_init(HASH *hash,uint default_array_elements, uint key_offset, my_bool hash_init(HASH *hash,CHARSET_INFO *charset,
uint default_array_elements, uint key_offset,
uint key_length, hash_get_key get_key, uint key_length, hash_get_key get_key,
void (*free_element)(void*), uint flags); void (*free_element)(void*), uint flags);
void hash_free(HASH *tree); void hash_free(HASH *tree);
......
...@@ -31,12 +31,13 @@ ...@@ -31,12 +31,13 @@
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength); static uint hash_mask(uint hashnr,uint buffmax,uint 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 uint calc_hashnr(const byte *key,uint length); static uint calc_hashnr(CHARSET_INFO *cs,const byte *key,uint length);
static uint calc_hashnr_caseup(const byte *key,uint length); static uint calc_hashnr_caseup(CHARSET_INFO *cs, const byte *key,uint length);
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length); static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length);
my_bool hash_init(HASH *hash,uint size,uint key_offset,uint key_length, my_bool hash_init(HASH *hash,CHARSET_INFO *charset,
uint size,uint key_offset,uint key_length,
hash_get_key get_key, hash_get_key get_key,
void (*free_element)(void*),uint flags) void (*free_element)(void*),uint flags)
{ {
...@@ -56,6 +57,7 @@ my_bool hash_init(HASH *hash,uint size,uint key_offset,uint key_length, ...@@ -56,6 +57,7 @@ my_bool hash_init(HASH *hash,uint size,uint key_offset,uint key_length,
hash->get_key=get_key; hash->get_key=get_key;
hash->free=free_element; hash->free=free_element;
hash->flags=flags; hash->flags=flags;
hash->charset=charset;
if (flags & HASH_CASE_INSENSITIVE) if (flags & HASH_CASE_INSENSITIVE)
hash->calc_hashnr=calc_hashnr_caseup; hash->calc_hashnr=calc_hashnr_caseup;
else else
...@@ -104,14 +106,15 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, ...@@ -104,14 +106,15 @@ static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax,
{ {
uint length; uint length;
byte *key=hash_key(hash,pos->data,&length,0); byte *key=hash_key(hash,pos->data,&length,0);
return hash_mask((*hash->calc_hashnr)(key,length),buffmax,maxlength); return hash_mask((*hash->calc_hashnr)(hash->charset,key,length),
buffmax,maxlength);
} }
#ifndef NEW_HASH_FUNCTION #ifndef NEW_HASH_FUNCTION
/* Calc hashvalue for a key */ /* Calc hashvalue for a key */
static uint calc_hashnr(const byte *key,uint length) static uint calc_hashnr(CHARSET_INFO *cs, const byte *key,uint length)
{ {
register uint nr=1, nr2=4; register uint nr=1, nr2=4;
while (length--) while (length--)
...@@ -124,14 +127,13 @@ static uint calc_hashnr(const byte *key,uint length) ...@@ -124,14 +127,13 @@ static uint calc_hashnr(const byte *key,uint length)
/* Calc hashvalue for a key, case indepenently */ /* Calc hashvalue for a key, case indepenently */
static uint calc_hashnr_caseup(const byte *key,uint length) static uint calc_hashnr_caseup(CHARSET_INFO *cs, const byte *key,uint length)
{ {
register uint nr=1, nr2=4; register uint nr=1, nr2=4;
while (length--) while (length--)
{ {
/* BAR TODO: remove default_charset_info */
nr^= (((nr & 63)+nr2)* nr^= (((nr & 63)+nr2)*
((uint) (uchar) my_toupper(default_charset_info, *key++)))+ (nr << 8); ((uint) (uchar) my_toupper(cs, *key++)))+ (nr << 8);
nr2+=3; nr2+=3;
} }
return((uint) nr); return((uint) nr);
...@@ -152,7 +154,7 @@ static uint calc_hashnr_caseup(const byte *key,uint length) ...@@ -152,7 +154,7 @@ static uint calc_hashnr_caseup(const byte *key,uint length)
* This works well on both numbers and strings. * This works well on both numbers and strings.
*/ */
uint calc_hashnr(const byte *key, uint len) uint calc_hashnr(CHARSET_INFO *cs, const byte *key, uint len)
{ {
const byte *end=key+len; const byte *end=key+len;
uint hash; uint hash;
...@@ -164,14 +166,14 @@ uint calc_hashnr(const byte *key, uint len) ...@@ -164,14 +166,14 @@ uint calc_hashnr(const byte *key, uint len)
return (hash); return (hash);
} }
uint calc_hashnr_caseup(const byte *key, uint len) uint calc_hashnr_caseup(CHARSET_INFO *cs, const byte *key, uint len)
{ {
const byte *end=key+len; const byte *end=key+len;
uint hash; uint hash;
for (hash = 0; key < end; key++) for (hash = 0; key < end; key++)
{ {
hash *= 16777619; hash *= 16777619;
hash ^= (uint) (uchar) toupper(*key); hash ^= (uint) (uchar) my_toupper(cs,*key);
} }
return (hash); return (hash);
} }
...@@ -186,7 +188,7 @@ uint rec_hashnr(HASH *hash,const byte *record) ...@@ -186,7 +188,7 @@ uint rec_hashnr(HASH *hash,const byte *record)
{ {
uint length; uint length;
byte *key=hash_key(hash,record,&length,0); byte *key=hash_key(hash,record,&length,0);
return (*hash->calc_hashnr)(key,length); return (*hash->calc_hashnr)(hash->charset,key,length);
} }
...@@ -202,7 +204,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length) ...@@ -202,7 +204,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length)
flag=1; flag=1;
if (hash->records) if (hash->records)
{ {
idx=hash_mask((*hash->calc_hashnr)(key,length ? length : idx=hash_mask((*hash->calc_hashnr)(hash->charset,key,length ? length :
hash->key_length), hash->key_length),
hash->blength,hash->records); hash->blength,hash->records);
do do
...@@ -516,7 +518,7 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length) ...@@ -516,7 +518,7 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
/* Search after record with key */ /* Search after record with key */
idx=hash_mask((*hash->calc_hashnr)(old_key,(old_key_length ? idx=hash_mask((*hash->calc_hashnr)(hash->charset, old_key,(old_key_length ?
old_key_length : old_key_length :
hash->key_length)), hash->key_length)),
blength,records); blength,records);
......
...@@ -168,7 +168,7 @@ bool berkeley_init(void) ...@@ -168,7 +168,7 @@ bool berkeley_init(void)
db_env=0; /* purecov: inspected */ db_env=0; /* purecov: inspected */
} }
(void) hash_init(&bdb_open_tables,32,0,0, (void) hash_init(&bdb_open_tables,system_charset_info,32,0,0,
(hash_get_key) bdb_get_key,0,0); (hash_get_key) bdb_get_key,0,0);
pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST);
DBUG_RETURN(db_env == 0); DBUG_RETURN(db_env == 0);
......
...@@ -666,7 +666,7 @@ innobase_init(void) ...@@ -666,7 +666,7 @@ innobase_init(void)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
(void) hash_init(&innobase_open_tables,32,0,0, (void) hash_init(&innobase_open_tables,system_charset_info,32,0,0,
(hash_get_key) innobase_get_key,0,0); (hash_get_key) innobase_get_key,0,0);
pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&innobase_mutex,MY_MUTEX_INIT_FAST);
DBUG_RETURN(0); DBUG_RETURN(0);
......
...@@ -75,8 +75,8 @@ class hash_filo ...@@ -75,8 +75,8 @@ class hash_filo
if (!locked) if (!locked)
(void) pthread_mutex_lock(&lock); (void) pthread_mutex_lock(&lock);
(void) hash_free(&cache); (void) hash_free(&cache);
(void) hash_init(&cache,size,key_offset, key_length, get_key, free_element, (void) hash_init(&cache,system_charset_info,size,key_offset,
0); key_length, get_key, free_element,0);
if (!locked) if (!locked)
(void) pthread_mutex_unlock(&lock); (void) pthread_mutex_unlock(&lock);
first_link=last_link=0; first_link=last_link=0;
......
...@@ -1421,7 +1421,8 @@ char *ull_get_key(const ULL *ull,uint *length, ...@@ -1421,7 +1421,8 @@ char *ull_get_key(const ULL *ull,uint *length,
void item_user_lock_init(void) void item_user_lock_init(void)
{ {
pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
hash_init(&hash_user_locks,16,0,0,(hash_get_key) ull_get_key,NULL,0); hash_init(&hash_user_locks,system_charset_info,
16,0,0,(hash_get_key) ull_get_key,NULL,0);
} }
void item_user_lock_free(void) void item_user_lock_free(void)
......
...@@ -184,7 +184,7 @@ static void slave_info_free(void *s) ...@@ -184,7 +184,7 @@ static void slave_info_free(void *s)
void init_slave_list() void init_slave_list()
{ {
hash_init(&slave_list, SLAVE_LIST_CHUNK, 0, 0, hash_init(&slave_list, system_charset_info, SLAVE_LIST_CHUNK, 0, 0,
(hash_get_key) slave_list_key, slave_info_free, 0); (hash_get_key) slave_list_key, slave_info_free, 0);
pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_slave_list, MY_MUTEX_INIT_FAST);
} }
......
...@@ -470,7 +470,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, ...@@ -470,7 +470,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
void init_table_rule_hash(HASH* h, bool* h_inited) void init_table_rule_hash(HASH* h, bool* h_inited)
{ {
hash_init(h, TABLE_RULE_HASH_SIZE,0,0, hash_init(h, system_charset_info,TABLE_RULE_HASH_SIZE,0,0,
(hash_get_key) get_table_key, (hash_get_key) get_table_key,
(void (*)(void*)) free_table_ent, 0); (void (*)(void*)) free_table_ent, 0);
*h_inited = 1; *h_inited = 1;
......
...@@ -847,7 +847,7 @@ static void init_check_host(void) ...@@ -847,7 +847,7 @@ static void init_check_host(void)
DBUG_ENTER("init_check_host"); DBUG_ENTER("init_check_host");
VOID(init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), VOID(init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip),
acl_users.elements,1)); acl_users.elements,1));
VOID(hash_init(&acl_check_hosts,acl_users.elements,0,0, VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0,
(hash_get_key) check_get_key,0,HASH_CASE_INSENSITIVE)); (hash_get_key) check_get_key,0,HASH_CASE_INSENSITIVE));
if (!allow_all_hosts) if (!allow_all_hosts)
{ {
...@@ -1424,7 +1424,8 @@ class GRANT_TABLE :public Sql_alloc ...@@ -1424,7 +1424,8 @@ class GRANT_TABLE :public Sql_alloc
key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3;
hash_key = (char*) alloc_root(&memex,key_length); hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
(void) hash_init(&hash_columns,0,0,0, (hash_get_key) get_key_column,0, (void) hash_init(&hash_columns,system_charset_info,
0,0,0, (hash_get_key) get_key_column,0,
HASH_CASE_INSENSITIVE); HASH_CASE_INSENSITIVE);
} }
...@@ -1456,7 +1457,8 @@ class GRANT_TABLE :public Sql_alloc ...@@ -1456,7 +1457,8 @@ class GRANT_TABLE :public Sql_alloc
privs = fix_rights_for_table(privs); privs = fix_rights_for_table(privs);
cols = fix_rights_for_column(cols); cols = fix_rights_for_column(cols);
(void) hash_init(&hash_columns,0,0,0, (hash_get_key) get_key_column,0, (void) hash_init(&hash_columns,system_charset_info,
0,0,0, (hash_get_key) get_key_column,0,
HASH_CASE_INSENSITIVE); HASH_CASE_INSENSITIVE);
if (cols) if (cols)
{ {
...@@ -2143,7 +2145,8 @@ int grant_init (void) ...@@ -2143,7 +2145,8 @@ int grant_init (void)
DBUG_ENTER("grant_init"); DBUG_ENTER("grant_init");
grant_option = FALSE; grant_option = FALSE;
(void) hash_init(&hash_tables,0,0,0, (hash_get_key) get_grant_table, (void) hash_init(&hash_tables,system_charset_info,
0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0); (hash_free_key) free_grant_table,0);
init_sql_alloc(&memex,1024,0); init_sql_alloc(&memex,1024,0);
......
...@@ -50,7 +50,7 @@ static byte *cache_key(const byte *record,uint *length, ...@@ -50,7 +50,7 @@ static byte *cache_key(const byte *record,uint *length,
void table_cache_init(void) void table_cache_init(void)
{ {
VOID(hash_init(&open_cache, VOID(hash_init(&open_cache,system_charset_info,
table_cache_size+16,0,0,cache_key, table_cache_size+16,0,0,cache_key,
(void (*)(void*)) free_cache_entry,0)); (void (*)(void*)) free_cache_entry,0));
mysql_rm_tmp_tables(); mysql_rm_tmp_tables();
......
...@@ -1330,9 +1330,9 @@ ulong Query_cache::init_cache() ...@@ -1330,9 +1330,9 @@ ulong Query_cache::init_cache()
DUMP(this); DUMP(this);
VOID(hash_init(&queries,def_query_hash_size, 0, 0, VOID(hash_init(&queries,system_charset_info,def_query_hash_size, 0, 0,
query_cache_query_get_key, 0, 0)); query_cache_query_get_key, 0, 0));
VOID(hash_init(&tables,def_table_hash_size, 0, 0, VOID(hash_init(&tables,system_charset_info,def_table_hash_size, 0, 0,
query_cache_table_get_key, 0, 0)); query_cache_table_get_key, 0, 0));
queries_in_cache = 0; queries_in_cache = 0;
......
...@@ -137,7 +137,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -137,7 +137,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
/* Initialize sub structures */ /* Initialize sub structures */
bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &mem_root,sizeof(mem_root));
user_connect=(UC *)0; user_connect=(UC *)0;
hash_init(&user_vars, USER_VARS_HASH_SIZE, 0, 0, hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key, (hash_get_key) get_var_key,
(void (*)(void*)) free_var,0); (void (*)(void*)) free_var,0);
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
......
...@@ -269,7 +269,8 @@ static void free_user(struct user_conn *uc) ...@@ -269,7 +269,8 @@ static void free_user(struct user_conn *uc)
void init_max_user_conn(void) void init_max_user_conn(void)
{ {
(void) hash_init(&hash_user_connections,max_connections,0,0, (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
0,0,
(hash_get_key) get_key_conn, (void (*)(void*)) free_user, (hash_get_key) get_key_conn, (void (*)(void*)) free_user,
0); 0);
} }
......
...@@ -5874,8 +5874,10 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, ...@@ -5874,8 +5874,10 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
(uint) (field_count*sizeof(*field_lengths)), (uint) (field_count*sizeof(*field_lengths)),
NullS)) NullS))
DBUG_RETURN(1); DBUG_RETURN(1);
if (hash_init(&hash, (uint) file->records, 0, key_length,
(hash_get_key) 0, 0, 0)) // BAR TODO: this must be fixed to use charset from "table" argument
if (hash_init(&hash, default_charset_info, (uint) file->records, 0,
key_length,(hash_get_key) 0, 0, 0))
{ {
my_free((char*) key_buffer,MYF(0)); my_free((char*) key_buffer,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
......
...@@ -127,7 +127,8 @@ void udf_init() ...@@ -127,7 +127,8 @@ void udf_init()
init_sql_alloc(&mem, 1024,0); init_sql_alloc(&mem, 1024,0);
THD *new_thd = new THD; THD *new_thd = new THD;
if (!new_thd || if (!new_thd ||
hash_init(&udf_hash,32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE)) hash_init(&udf_hash,system_charset_info,
32,0,0,get_hash_key, NULL, HASH_CASE_INSENSITIVE))
{ {
sql_print_error("Can't allocate memory for udf structures"); sql_print_error("Can't allocate memory for udf structures");
hash_free(&udf_hash); hash_free(&udf_hash);
......
...@@ -319,6 +319,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -319,6 +319,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
use_hash= outparam->fields >= MAX_FIELDS_BEFORE_HASH; use_hash= outparam->fields >= MAX_FIELDS_BEFORE_HASH;
if (use_hash) if (use_hash)
use_hash= !hash_init(&outparam->name_hash, use_hash= !hash_init(&outparam->name_hash,
system_charset_info,
outparam->fields,0,0, outparam->fields,0,0,
(hash_get_key) get_field_name,0, (hash_get_key) get_field_name,0,
HASH_CASE_INSENSITIVE); HASH_CASE_INSENSITIVE);
......
...@@ -1655,7 +1655,8 @@ static void init_user_hash() ...@@ -1655,7 +1655,8 @@ static void init_user_hash()
FILE* f; FILE* f;
char buf[80]; char buf[80];
int line_num=1; int line_num=1;
if (hash_init(&user_hash,1024,0,0,get_user_key,manager_user_free,MYF(0))) if (hash_init(&user_hash,system_charset_info,1024,0,0,
get_user_key,manager_user_free,MYF(0)))
die("Could not initialize user hash"); die("Could not initialize user hash");
if (!(f=fopen(manager_pw_file,"r"))) if (!(f=fopen(manager_pw_file,"r")))
die("Could not open password file '%s'", manager_pw_file); die("Could not open password file '%s'", manager_pw_file);
...@@ -1693,7 +1694,8 @@ static void init_pid_file() ...@@ -1693,7 +1694,8 @@ static void init_pid_file()
static void init_globals() static void init_globals()
{ {
pthread_attr_t thr_attr; pthread_attr_t thr_attr;
if (hash_init(&exec_hash,1024,0,0,get_exec_key,manager_exec_free,MYF(0))) if (hash_init(&exec_hash,system_charset_info,1024,0,0,
get_exec_key,manager_exec_free,MYF(0)))
die("Exec hash initialization failed"); die("Exec hash initialization failed");
if (!one_thread) if (!one_thread)
{ {
......
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