diff options
Diffstat (limited to 'mysys/hash.c')
-rw-r--r-- | mysys/hash.c | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/mysys/hash.c b/mysys/hash.c index 5ff3c2e99ce..b93f6b666d6 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* The hash functions used for saveing keys */ /* One of key_length or key_length_offset must be given */ @@ -33,16 +33,18 @@ typedef struct st_hash_info { uchar *data; /* data for current entry */ } 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 int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key, 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; hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2); - return nr1; + return (my_hash_value_type)nr1; } /** @@ -65,8 +67,6 @@ static uint calc_hash(const HASH *hash, const uchar *key, size_t length) @param[in] get_key get the key for the hash @param[in] free_element pointer to the function that does cleanup - @param[in] CALLER_INFO_PROTO flag that define the behaviour - of the hash @return inidicates success or failure of initialization @retval 0 success @retval 1 failure @@ -75,8 +75,9 @@ my_bool _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, ulong size, size_t key_offset, size_t key_length, my_hash_get_key get_key, - void (*free_element)(void*), uint flags CALLER_INFO_PROTO) + void (*free_element)(void*), uint flags) { + my_bool res; DBUG_ENTER("my_hash_init"); DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size)); @@ -88,8 +89,9 @@ _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, hash->free=free_element; hash->flags=flags; hash->charset=charset; - DBUG_RETURN(my_init_dynamic_array_ci(&hash->array, - sizeof(HASH_LINK), size, growth_size)); + res= my_init_dynamic_array_ci(&hash->array, + sizeof(HASH_LINK), size, growth_size); + DBUG_RETURN(res); } @@ -180,7 +182,8 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length, /* 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 (uint) (hashnr & (buffmax-1)); @@ -202,7 +205,7 @@ static #if !defined(__USLC__) && !defined(__sgi) inline #endif -unsigned int rec_hashnr(HASH *hash,const uchar *record) +my_hash_value_type rec_hashnr(HASH *hash,const uchar *record) { size_t length; uchar *key= (uchar*) my_hash_key(hash, record, &length, 0); @@ -216,6 +219,23 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length) 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 @@ -226,14 +246,31 @@ 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, HASH_SEARCH_STATE *current_record) { + uchar *res; + if (my_hash_inited(hash)) + res= my_hash_first_from_hash_value(hash, + calc_hash(hash, key, length ? length : hash->key_length), + key, length, current_record); + else + res= 0; + return res; +} + + +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; uint flag,idx; - DBUG_ENTER("my_hash_first"); + DBUG_ENTER("my_hash_first_from_hash_value"); flag=1; 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); do { @@ -339,7 +376,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key, my_bool my_hash_insert(HASH *info, const uchar *record) { 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); HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos; @@ -485,7 +523,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record) my_bool my_hash_delete(HASH *hash, uchar *record) { - uint pos2,pos_hashnr,lastpos_hashnr,idx,empty_index; + uint pos2,idx,empty_index; + my_hash_value_type pos_hashnr, lastpos_hashnr; size_t blength; HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; DBUG_ENTER("my_hash_delete"); @@ -560,7 +599,7 @@ my_bool my_hash_delete(HASH *hash, uchar *record) pos->next=empty_index; exit: - VOID(pop_dynamic(&hash->array)); + (void) pop_dynamic(&hash->array); if (hash->free) (*hash->free)((uchar*) record); DBUG_RETURN(0); |