31
31
typedef struct st_hash_info {
32
uint32_t next; /* index to next key */
33
unsigned char *data; /* data for current entry */
32
uint next; /* index to next key */
33
uchar *data; /* data for current entry */
36
static uint32_t hash_mask(uint32_t hashnr,uint32_t buffmax,uint32_t maxlength);
37
static void movelink(HASH_LINK *array,uint32_t pos,uint32_t next_link,uint32_t newlink);
38
static int hashcmp(const HASH *hash, HASH_LINK *pos, const unsigned char *key,
36
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength);
37
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
38
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
41
static uint32_t calc_hash(const HASH *hash, const unsigned char *key, size_t length)
41
static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
43
43
uint32_t nr1=1, nr2=4;
44
hash->charset->coll->hash_sort(hash->charset,(const unsigned char*) key,length,&nr1,&nr2);
44
hash->charset->coll->hash_sort(hash->charset,(const uchar*) key,length,&nr1,&nr2);
49
_hash_init(HASH *hash,uint32_t growth_size, const CHARSET_INFO * const charset,
49
_hash_init(HASH *hash,uint growth_size, const CHARSET_INFO * const charset,
50
50
uint32_t size, size_t key_offset, size_t key_length,
51
51
hash_get_key get_key,
52
void (*free_element)(void*),uint32_t flags CALLER_INFO_PROTO)
52
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
55
55
if (my_init_dynamic_array_ci(&hash->array, sizeof(HASH_LINK), size,
132
132
/* some helper functions */
135
This function is char* instead of unsigned char* as HPUX11 compiler can't
135
This function is char* instead of uchar* as HPUX11 compiler can't
136
136
handle inline functions that are not defined as native types
139
139
static inline char*
140
hash_key(const HASH *hash, const unsigned char *record, size_t *length,
140
hash_key(const HASH *hash, const uchar *record, size_t *length,
143
143
if (hash->get_key)
149
149
/* Calculate pos according to keys */
151
static uint32_t hash_mask(uint32_t hashnr,uint32_t buffmax,uint32_t maxlength)
151
static uint hash_mask(uint hashnr,uint buffmax,uint maxlength)
153
153
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
154
154
return (hashnr & ((buffmax >> 1) -1));
157
static uint32_t hash_rec_mask(const HASH *hash, HASH_LINK *pos,
158
uint32_t buffmax, uint32_t maxlength)
157
static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos,
158
uint buffmax, uint maxlength)
161
unsigned char *key= (unsigned char*) hash_key(hash,pos->data,&length,0);
161
uchar *key= (uchar*) hash_key(hash,pos->data,&length,0);
162
162
return hash_mask(calc_hash(hash,key,length),buffmax,maxlength);
169
169
#if !defined(__USLC__) && !defined(__sgi)
172
unsigned int rec_hashnr(HASH *hash,const unsigned char *record)
172
unsigned int rec_hashnr(HASH *hash,const uchar *record)
175
unsigned char *key= (unsigned char*) hash_key(hash,record,&length,0);
175
uchar *key= (uchar*) hash_key(hash,record,&length,0);
176
176
return calc_hash(hash,key,length);
180
unsigned char* hash_search(const HASH *hash, const unsigned char *key, size_t length)
180
uchar* hash_search(const HASH *hash, const uchar *key, size_t length)
182
182
HASH_SEARCH_STATE state;
183
183
return hash_first(hash, key, length, &state);
190
190
Assigns the number of the found record to HASH_SEARCH_STATE state
193
unsigned char* hash_first(const HASH *hash, const unsigned char *key, size_t length,
193
uchar* hash_first(const HASH *hash, const uchar *key, size_t length,
194
194
HASH_SEARCH_STATE *current_record)
200
200
if (hash->records)
225
225
/* Get next record with identical key */
226
226
/* Can only be called if previous calls was hash_search */
228
unsigned char* hash_next(const HASH *hash, const unsigned char *key, size_t length,
228
uchar* hash_next(const HASH *hash, const uchar *key, size_t length,
229
229
HASH_SEARCH_STATE *current_record)
234
234
if (*current_record != NO_RECORD)
252
252
/* Change link from pos to new_link */
254
static void movelink(HASH_LINK *array,uint32_t find,uint32_t next_link,uint32_t newlink)
254
static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
256
256
HASH_LINK *old_link;
282
282
!= 0 key of record != key
285
static int hashcmp(const HASH *hash, HASH_LINK *pos, const unsigned char *key,
285
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
288
288
size_t rec_keylength;
289
unsigned char *rec_key= (unsigned char*) hash_key(hash,pos->data,&rec_keylength,1);
289
uchar *rec_key= (uchar*) hash_key(hash,pos->data,&rec_keylength,1);
290
290
return ((length && length != rec_keylength) ||
291
my_strnncoll(hash->charset, (const unsigned char*) rec_key, rec_keylength,
292
(const unsigned char*) key, rec_keylength));
291
my_strnncoll(hash->charset, (const uchar*) rec_key, rec_keylength,
292
(const uchar*) key, rec_keylength));
296
296
/* Write a hash-key to the hash-index */
298
bool my_hash_insert(HASH *info,const unsigned char *record)
298
bool my_hash_insert(HASH *info,const uchar *record)
302
uint32_t halfbuff,hash_nr,first_index;
303
unsigned char *ptr_to_rec=NULL,*ptr_to_rec2=NULL;
302
uint halfbuff,hash_nr,first_index;
303
uchar *ptr_to_rec=NULL,*ptr_to_rec2=NULL;
304
304
HASH_LINK *data,*empty,*gpos=NULL,*gpos2=NULL,*pos;
306
306
if (HASH_UNIQUE & info->flags)
308
unsigned char *key= (unsigned char*) hash_key(info, record, &idx, 1);
308
uchar *key= (uchar*) hash_key(info, record, &idx, 1);
309
309
if (hash_search(info, key, idx))
310
310
return(true); /* Duplicate entry */
411
411
gpos=data+hash_rec_mask(info,pos,info->blength,info->records+1);
414
pos->data=(unsigned char*) record;
414
pos->data=(uchar*) record;
415
415
pos->next=(uint) (empty - data);
419
pos->data=(unsigned char*) record;
419
pos->data=(uchar*) record;
420
420
pos->next=NO_RECORD;
421
421
movelink(data,(uint) (pos-data),(uint) (gpos-data),(uint) (empty-data));
433
433
** if there is a free-function it's called for record if found
434
434
******************************************************************************/
436
bool hash_delete(HASH *hash,unsigned char *record)
436
bool hash_delete(HASH *hash,uchar *record)
438
uint32_t blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
438
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
439
439
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
440
440
if (!hash->records)
519
519
This is much more efficent than using a delete & insert.
522
bool hash_update(HASH *hash, unsigned char *record, unsigned char *old_key,
522
bool hash_update(HASH *hash, uchar *record, uchar *old_key,
523
523
size_t old_key_length)
525
uint32_t new_index,new_pos_index,blength,records,empty;
525
uint new_index,new_pos_index,blength,records,empty;
527
527
HASH_LINK org_link,*data,*previous,*pos;
529
529
if (HASH_UNIQUE & hash->flags)
531
531
HASH_SEARCH_STATE state;
532
unsigned char *found, *new_key= (unsigned char*) hash_key(hash, record, &idx, 1);
532
uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1);
533
533
if ((found= hash_first(hash, new_key, idx, &state)))
634
void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, unsigned char *new_row)
634
void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, uchar *new_row)
636
636
if (*current_record != NO_RECORD) /* Safety */
637
637
dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;