00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "heap_priv.h"
00019 #include <drizzled/error_t.h>
00020 #include <drizzled/internal/my_sys.h>
00021
00022 int heap_delete(HP_INFO *info, const unsigned char *record)
00023 {
00024 unsigned char *pos;
00025 HP_SHARE *share=info->getShare();
00026 HP_KEYDEF *keydef, *end, *p_lastinx;
00027
00028 test_active(info);
00029
00030 if (info->opt_flag & READ_CHECK_USED)
00031 return(errno);
00032 share->changed=1;
00033
00034 if ( --(share->records) < share->blength >> 1) share->blength>>=1;
00035 pos=info->current_ptr;
00036
00037 p_lastinx = share->keydef + info->lastinx;
00038 for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
00039 keydef++)
00040 {
00041 if (hp_delete_key(info, keydef, record, pos, keydef == p_lastinx))
00042 goto err;
00043 }
00044
00045 info->update=HA_STATE_DELETED;
00046 hp_free_chunks(&share->recordspace, pos);
00047 info->current_hash_ptr=0;
00048
00049 return(0);
00050 err:
00051 if (++(share->records) == share->blength)
00052 share->blength+= share->blength;
00053 return(errno);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
00074 const unsigned char *record, unsigned char *recpos, int flag)
00075 {
00076 uint32_t blength,pos2,pos_hashnr,lastpos_hashnr;
00077 HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
00078 HP_SHARE *share=info->getShare();
00079
00080 blength=share->blength;
00081 if (share->records+1 == blength)
00082 blength+= blength;
00083
00084
00085
00086 lastpos=hp_find_hash(&keyinfo->block,share->records);
00087 last_ptr=0;
00088
00089
00090 pos= hp_find_hash(&keyinfo->block,
00091 hp_mask(hp_rec_hashnr(keyinfo, record), blength,
00092 share->records + 1));
00093 gpos = pos3 = 0;
00094
00095 while (pos->ptr_to_rec != recpos)
00096 {
00097 if (flag && !hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 0))
00098 last_ptr=pos;
00099 gpos=pos;
00100 if (!(pos=pos->next_key))
00101 {
00102 return(errno= drizzled::HA_ERR_CRASHED);
00103 }
00104 }
00105
00106
00107
00108 if (flag)
00109 {
00110
00111 info->current_hash_ptr=last_ptr;
00112 info->current_ptr = last_ptr ? last_ptr->ptr_to_rec : 0;
00113 }
00114 empty=pos;
00115 if (gpos) {
00116
00117 gpos->next_key=pos->next_key;
00118 }
00119 else if (pos->next_key)
00120 {
00121
00122
00123
00124 empty=pos->next_key;
00125 pos->ptr_to_rec=empty->ptr_to_rec;
00126 pos->next_key=empty->next_key;
00127 }
00128 else
00129 {
00130
00131 keyinfo->hash_buckets--;
00132 }
00133
00134 if (empty == lastpos)
00135 return (0);
00136
00137
00138 lastpos_hashnr = hp_rec_hashnr(keyinfo, lastpos->ptr_to_rec);
00139
00140 pos=hp_find_hash(&keyinfo->block, hp_mask(lastpos_hashnr, share->blength,
00141 share->records));
00142 if (pos == empty)
00143 {
00144 empty[0]=lastpos[0];
00145 return(0);
00146 }
00147 pos_hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
00148
00149 pos3= hp_find_hash(&keyinfo->block,
00150 hp_mask(pos_hashnr, share->blength, share->records));
00151 if (pos != pos3)
00152 {
00153 empty[0]=pos[0];
00154 pos[0]=lastpos[0];
00155 hp_movelink(pos, pos3, empty);
00156 return(0);
00157 }
00158 pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
00159 if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
00160 {
00161 if (pos2 != share->records)
00162 {
00163 empty[0]=lastpos[0];
00164 hp_movelink(lastpos, pos, empty);
00165 return(0);
00166 }
00167 pos3= pos;
00168 }
00169 else
00170 {
00171 pos3= 0;
00172 keyinfo->hash_buckets--;
00173 }
00174
00175 empty[0]=lastpos[0];
00176 hp_movelink(pos3, empty, pos->next_key);
00177 pos->next_key=empty;
00178 return(0);
00179 }