428
/******************************************************************************
429
** Remove one record from hash-table. The record with the same record
431
** if there is a free-function it's called for record if found
432
*****************************************************************************/
434
bool hash_delete(HASH *hash,unsigned char *record)
436
uint32_t blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
437
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
441
blength=hash->blength;
442
data=dynamic_element(&hash->array,0,HASH_LINK*);
443
/* Search after record with key */
444
pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records);
447
while (pos->data != record)
450
if (pos->next == NO_RECORD)
457
if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
458
lastpos=data+hash->records;
460
/* Remove link to record */
461
empty=pos; empty_index=(uint32_t) (empty-data);
463
/* unlink current ptr */
464
gpos->next=pos->next;
465
else if (pos->next != NO_RECORD)
467
empty=data+(empty_index=pos->next);
468
pos->data=empty->data;
469
pos->next=empty->next;
472
/* last key at wrong pos or no next link */
473
if (empty == lastpos)
476
/* Move the last key (lastpos) */
477
lastpos_hashnr=rec_hashnr(hash,lastpos->data);
478
/* pos is where lastpos should be */
479
pos=data+hash_mask(lastpos_hashnr,hash->blength,hash->records);
480
/* Move to empty position. */
486
pos_hashnr=rec_hashnr(hash,pos->data);
487
/* pos3 is where the pos should be */
488
pos3= data+hash_mask(pos_hashnr,hash->blength,hash->records);
490
{ /* pos is on wrong posit */
491
empty[0]=pos[0]; /* Save it here */
492
pos[0]=lastpos[0]; /* This should be here */
493
movelink(data,(uint32_t) (pos-data),(uint32_t) (pos3-data),empty_index);
496
pos2= hash_mask(lastpos_hashnr,blength,hash->records+1);
497
if (pos2 == hash_mask(pos_hashnr,blength,hash->records+1))
498
{ /* Identical key-positions */
499
if (pos2 != hash->records)
502
movelink(data,(uint32_t) (lastpos-data),(uint32_t) (pos-data),empty_index);
505
idx= (uint32_t) (pos-data); /* Link pos->next after lastpos */
507
else idx= NO_RECORD; /* Different positions merge */
510
movelink(data,idx,empty_index,pos->next);
511
pos->next=empty_index;
514
pop_dynamic(&hash->array);
516
(*hash->free)((unsigned char*) record);
520
427
unsigned char *hash_element(HASH *hash,uint32_t idx)
522
429
if (idx < hash->records)