| 522 | ******************************************************************************/ |
| 523 | |
| 524 | my_bool my_hash_delete(HASH *hash, uchar *record) |
| 525 | { |
| 526 | uint blength,pos2,idx,empty_index; |
| 527 | my_hash_value_type pos_hashnr, lastpos_hashnr; |
| 528 | HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; |
| 529 | DBUG_ENTER("my_hash_delete"); |
| 530 | if (!hash->records) |
| 531 | DBUG_RETURN(1); |
| 532 | |
| 533 | blength=hash->blength; |
| 534 | data=dynamic_element(&hash->array,0,HASH_LINK*); |
| 535 | /* Search after record with key */ |
| 536 | pos= data + my_hash_mask(rec_hashnr(hash, record), blength, hash->records); |
| 537 | gpos = 0; |
| 538 | |
| 539 | while (pos->data != record) |
| 540 | { |
| 541 | gpos=pos; |
| 542 | if (pos->next == NO_RECORD) |
| 543 | DBUG_RETURN(1); /* Key not found */ |
| 544 | pos=data+pos->next; |
| 545 | } |
| 546 | |
| 547 | if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1; |
| 548 | lastpos=data+hash->records; |
| 549 | |
| 550 | /* Remove link to record */ |
| 551 | empty=pos; empty_index=(uint) (empty-data); |
| 552 | if (gpos) |
| 553 | gpos->next=pos->next; /* unlink current ptr */ |
| 554 | else if (pos->next != NO_RECORD) |
| 555 | { |
| 556 | empty=data+(empty_index=pos->next); |
| 557 | pos->data=empty->data; |
| 558 | pos->next=empty->next; |
| 559 | } |
| 560 | |
| 561 | if (empty == lastpos) /* last key at wrong pos or no next link */ |
| 562 | goto exit; |
| 563 | |
| 564 | /* Move the last key (lastpos) */ |
| 565 | lastpos_hashnr=rec_hashnr(hash,lastpos->data); |
| 566 | /* pos is where lastpos should be */ |
| 567 | pos= data + my_hash_mask(lastpos_hashnr, hash->blength, hash->records); |
| 568 | if (pos == empty) /* Move to empty position. */ |
| 569 | { |
| 570 | empty[0]=lastpos[0]; |
| 571 | goto exit; |
| 572 | } |
| 573 | pos_hashnr=rec_hashnr(hash,pos->data); |
| 574 | /* pos3 is where the pos should be */ |
| 575 | pos3= data + my_hash_mask(pos_hashnr, hash->blength, hash->records); |
| 576 | if (pos != pos3) |
| 577 | { /* pos is on wrong posit */ |
| 578 | empty[0]=pos[0]; /* Save it here */ |
| 579 | pos[0]=lastpos[0]; /* This should be here */ |
| 580 | movelink(data,(uint) (pos-data),(uint) (pos3-data),empty_index); |
| 581 | goto exit; |
no test coverage detected