~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_delete.c

  • Committer: Andy Lester
  • Date: 2008-08-10 02:15:48 UTC
  • mto: (266.1.31 use-replace-funcs)
  • mto: This revision was merged to the branch mainline in revision 295.
  • Revision ID: andy@petdance.com-20080810021548-0zx8nhzva6al10k3
Added a proper const qualifer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* Remove a row from a MyISAM table */
17
17
 
18
18
#include "myisamdef.h"
19
 
#include <drizzled/util/test.h>
20
19
 
21
 
static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint32_t comp_flag,
22
 
                    unsigned char *key,uint32_t key_length,my_off_t page,unsigned char *anc_buff);
23
 
static int del(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,unsigned char *anc_buff,
24
 
               my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos,
25
 
               my_off_t next_block,unsigned char *ret_key);
26
 
static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *anc_buff,
27
 
                     my_off_t leaf_page,unsigned char *leaf_buff,unsigned char *keypos);
28
 
static uint32_t remove_key(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *keypos,
29
 
                       unsigned char *lastkey,unsigned char *page_end,
 
20
static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint comp_flag,
 
21
                    uchar *key,uint key_length,my_off_t page,uchar *anc_buff);
 
22
static int del(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uchar *anc_buff,
 
23
               my_off_t leaf_page,uchar *leaf_buff,uchar *keypos,
 
24
               my_off_t next_block,uchar *ret_key);
 
25
static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *anc_buff,
 
26
                     my_off_t leaf_page,uchar *leaf_buff,uchar *keypos);
 
27
static uint remove_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar *keypos,
 
28
                       uchar *lastkey,uchar *page_end,
30
29
                       my_off_t *next_block);
31
30
static int _mi_ck_real_delete(register MI_INFO *info,MI_KEYDEF *keyinfo,
32
 
                              unsigned char *key, uint32_t key_length, my_off_t *root);
33
 
 
34
 
 
35
 
int mi_delete(MI_INFO *info,const unsigned char *record)
 
31
                              uchar *key, uint key_length, my_off_t *root);
 
32
 
 
33
 
 
34
int mi_delete(MI_INFO *info,const uchar *record)
36
35
{
37
 
  uint32_t i;
38
 
  unsigned char *old_key;
 
36
  uint i;
 
37
  uchar *old_key;
39
38
  int save_errno;
40
39
  char lastpos[8];
41
40
 
86
85
  info->state->records--;
87
86
 
88
87
  mi_sizestore(lastpos,info->lastpos);
89
 
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
 
88
  myisam_log_command(MI_LOG_DELETE,info,(uchar*) lastpos,sizeof(lastpos),0);
 
89
  VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
90
90
  if (info->invalidator != 0)
91
91
  {
92
92
    (*info->invalidator)(info->filename);
97
97
err:
98
98
  save_errno=my_errno;
99
99
  mi_sizestore(lastpos,info->lastpos);
 
100
  myisam_log_command(MI_LOG_DELETE,info,(uchar*) lastpos, sizeof(lastpos),0);
100
101
  if (save_errno != HA_ERR_RECORD_CHANGED)
101
102
  {
102
103
    mi_print_error(info->s, HA_ERR_CRASHED);
103
104
    mi_mark_crashed(info);              /* mark table crashed */
104
105
  }
105
 
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
 
106
  VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
106
107
  info->update|=HA_STATE_WRITTEN;       /* Buffer changed */
107
108
  my_errno=save_errno;
108
109
  if (save_errno == HA_ERR_KEY_NOT_FOUND)
117
118
 
118
119
        /* Remove a key from the btree index */
119
120
 
120
 
int _mi_ck_delete(register MI_INFO *info, uint32_t keynr, unsigned char *key,
121
 
                  uint32_t key_length)
 
121
int _mi_ck_delete(register MI_INFO *info, uint keynr, uchar *key,
 
122
                  uint key_length)
122
123
{
123
124
  return _mi_ck_real_delete(info, info->s->keyinfo+keynr, key, key_length,
124
125
                            &info->s->state.key_root[keynr]);
126
127
 
127
128
 
128
129
static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
129
 
                              unsigned char *key, uint32_t key_length, my_off_t *root)
 
130
                              uchar *key, uint key_length, my_off_t *root)
130
131
{
131
132
  int error;
132
 
  uint32_t nod_flag;
 
133
  uint nod_flag;
133
134
  my_off_t old_root;
134
 
  unsigned char *root_buff;
 
135
  uchar *root_buff;
135
136
 
136
137
  if ((old_root=*root) == HA_OFFSET_ERROR)
137
138
  {
138
139
    mi_print_error(info->s, HA_ERR_CRASHED);
139
140
    return(my_errno=HA_ERR_CRASHED);
140
141
  }
141
 
  if (!(root_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
 
142
  if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
142
143
                                      MI_MAX_KEY_BUFF*2)))
143
144
  {
144
145
    return(my_errno=ENOMEM);
172
173
    }
173
174
  }
174
175
err:
175
 
  my_afree((unsigned char*) root_buff);
 
176
  my_afree((uchar*) root_buff);
176
177
  return(error);
177
178
} /* _mi_ck_real_delete */
178
179
 
186
187
        */
187
188
 
188
189
static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
189
 
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length,
190
 
                    my_off_t page, unsigned char *anc_buff)
 
190
                    uint comp_flag, uchar *key, uint key_length,
 
191
                    my_off_t page, uchar *anc_buff)
191
192
{
192
193
  int flag,ret_value,save_flag;
193
 
  uint32_t length,nod_flag,search_key_length;
194
 
  bool last_key;
195
 
  unsigned char *leaf_buff,*keypos;
 
194
  uint length,nod_flag,search_key_length;
 
195
  my_bool last_key;
 
196
  uchar *leaf_buff,*keypos;
196
197
  my_off_t leaf_page= 0, next_block;
197
 
  unsigned char lastkey[MI_MAX_KEY_BUFF];
 
198
  uchar lastkey[MI_MAX_KEY_BUFF];
198
199
 
199
200
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
200
201
  flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
209
210
  if (nod_flag)
210
211
  {
211
212
    leaf_page=_mi_kpos(nod_flag,keypos);
212
 
    if (!(leaf_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
 
213
    if (!(leaf_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
213
214
                                        MI_MAX_KEY_BUFF*2)))
214
215
    {
215
216
      my_errno=ENOMEM;
233
234
  }
234
235
  else
235
236
  {                                             /* Found key */
236
 
    uint32_t tmp;
 
237
    uint tmp;
237
238
    length=mi_getint(anc_buff);
238
239
    if (!(tmp= remove_key(keyinfo,nod_flag,keypos,lastkey,anc_buff+length,
239
240
                          &next_block)))
268
269
        goto err;
269
270
      }
270
271
      ret_value=_mi_insert(info,keyinfo,key,anc_buff,keypos,lastkey,
271
 
                           (unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,(bool) 0);
 
272
                           (uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
272
273
    }
273
274
  }
274
275
  if (ret_value == 0 && mi_getint(anc_buff) > keyinfo->block_length)
278
279
  }
279
280
  if (save_flag && ret_value != 1)
280
281
    ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
281
 
  my_afree((unsigned char*) leaf_buff);
 
282
  my_afree((uchar*) leaf_buff);
282
283
  return(ret_value);
283
284
 
284
285
err:
285
 
  my_afree((unsigned char*) leaf_buff);
 
286
  my_afree((uchar*) leaf_buff);
286
287
  return (-1);
287
288
} /* d_search */
288
289
 
289
290
 
290
291
        /* Remove a key that has a page-reference */
291
292
 
292
 
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *key,
293
 
               unsigned char *anc_buff, my_off_t leaf_page, unsigned char *leaf_buff,
294
 
               unsigned char *keypos,           /* Pos to where deleted key was */
 
293
static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
 
294
               uchar *anc_buff, my_off_t leaf_page, uchar *leaf_buff,
 
295
               uchar *keypos,           /* Pos to where deleted key was */
295
296
               my_off_t next_block,
296
 
               unsigned char *ret_key)          /* key before keypos in anc_buff */
 
297
               uchar *ret_key)          /* key before keypos in anc_buff */
297
298
{
298
299
  int ret_value,length;
299
 
  uint32_t a_length,nod_flag,tmp;
 
300
  uint a_length,nod_flag,tmp;
300
301
  my_off_t next_page;
301
 
  unsigned char keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
 
302
  uchar keybuff[MI_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
302
303
  MYISAM_SHARE *share=info->s;
303
304
  MI_KEY_PARAM s_temp;
304
305
 
310
311
  if ((nod_flag=mi_test_if_nod(leaf_buff)))
311
312
  {
312
313
    next_page= _mi_kpos(nod_flag,endpos);
313
 
    if (!(next_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
 
314
    if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
314
315
                                        MI_MAX_KEY_BUFF*2)))
315
316
      return(-1);
316
317
    if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
336
337
                                &tmp))
337
338
            goto err;
338
339
          ret_value=_mi_insert(info,keyinfo,key,leaf_buff,endpos,keybuff,
339
 
                               (unsigned char*) 0,(unsigned char*) 0,(my_off_t) 0,0);
 
340
                               (uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
340
341
        }
341
342
      }
342
343
      if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
343
344
        goto err;
344
345
    }
345
 
    my_afree((unsigned char*) next_buff);
 
346
    my_afree((uchar*) next_buff);
346
347
    return(ret_value);
347
348
  }
348
349
 
362
363
  prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
363
364
            0 : ret_key);
364
365
  length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
365
 
                              keypos == endpos ? (unsigned char*) 0 : keypos,
 
366
                              keypos == endpos ? (uchar*) 0 : keypos,
366
367
                              prev_key, prev_key,
367
368
                              keybuff,&s_temp);
368
369
  if (length > 0)
369
 
    bmove_upp((unsigned char*) endpos+length,(unsigned char*) endpos,(uint) (endpos-keypos));
 
370
    bmove_upp((uchar*) endpos+length,(uchar*) endpos,(uint) (endpos-keypos));
370
371
  else
371
372
    memcpy(keypos,keypos-length, (int) (endpos-keypos)+length);
372
373
  (*keyinfo->store_key)(keyinfo,keypos,&s_temp);
387
388
        /* Balances adjacent pages if underflow occours */
388
389
 
389
390
static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
390
 
                     unsigned char *anc_buff,
 
391
                     uchar *anc_buff,
391
392
                     my_off_t leaf_page,/* Ancestor page and underflow page */
392
 
                     unsigned char *leaf_buff,
393
 
                     unsigned char *keypos)     /* Position to pos after key */
 
393
                     uchar *leaf_buff,
 
394
                     uchar *keypos)     /* Position to pos after key */
394
395
{
395
396
  int t_length;
396
 
  uint32_t length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
 
397
  uint length,anc_length,buff_length,leaf_length,p_length,s_length,nod_flag,
397
398
       key_reflength,key_length;
398
399
  my_off_t next_page;
399
 
  unsigned char anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
 
400
  uchar anc_key[MI_MAX_KEY_BUFF],leaf_key[MI_MAX_KEY_BUFF],
400
401
        *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*temp_pos,*prev_key,
401
402
        *after_key;
402
403
  MI_KEY_PARAM s_temp;
443
444
      goto err;
444
445
 
445
446
    /* merge pages and put parting key from anc_buff between */
446
 
    prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
 
447
    prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
447
448
    t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,buff+p_length,
448
449
                                  prev_key, prev_key,
449
450
                                  anc_key, &s_temp);
450
451
    length=buff_length-p_length;
451
452
    endpos=buff+length+leaf_length+t_length;
452
453
    /* buff will always be larger than before !*/
453
 
    bmove_upp((unsigned char*) endpos, (unsigned char*) buff+buff_length,length);
 
454
    bmove_upp((uchar*) endpos, (uchar*) buff+buff_length,length);
454
455
    memcpy(buff, leaf_buff, leaf_length);
455
456
    (*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
456
457
    buff_length=(uint) (endpos-buff);
488
489
      half_pos=after_key;
489
490
      _mi_kpointer(info,leaf_key+key_length,next_page);
490
491
      /* Save key in anc_buff */
491
 
      prev_key=(keypos == anc_buff+2+key_reflength ? (unsigned char*) 0 : anc_key),
 
492
      prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key),
492
493
      t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
493
 
                                    (keypos == endpos ? (unsigned char*) 0 :
 
494
                                    (keypos == endpos ? (uchar*) 0 :
494
495
                                     keypos),
495
496
                                    prev_key, prev_key,
496
497
                                    leaf_key, &s_temp);
497
498
      if (t_length >= 0)
498
 
        bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,
 
499
        bmove_upp((uchar*) endpos+t_length,(uchar*) endpos,
499
500
                  (uint) (endpos-keypos));
500
501
      else
501
502
        memcpy(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
507
508
        memcpy(buff + 2, half_pos - nod_flag, nod_flag);
508
509
      if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
509
510
        goto err;
510
 
      t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (unsigned char*) 0,
511
 
                                          (unsigned char*) 0, (unsigned char *) 0,
 
511
      t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
 
512
                                          (uchar*) 0, (uchar *) 0,
512
513
                                          leaf_key, &s_temp);
513
514
      /* t_length will always be > 0 for a new page !*/
514
515
      length=(uint) ((buff+mi_getint(buff))-half_pos);
544
545
    goto err;
545
546
 
546
547
  /* merge pages and put parting key from anc_buff between */
547
 
  prev_key=(leaf_length == p_length ? (unsigned char*) 0 : leaf_key);
 
548
  prev_key=(leaf_length == p_length ? (uchar*) 0 : leaf_key);
548
549
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
549
550
                                (leaf_length == p_length ?
550
 
                                 (unsigned char*) 0 : leaf_buff+p_length),
 
551
                                 (uchar*) 0 : leaf_buff+p_length),
551
552
                                prev_key, prev_key,
552
553
                                anc_key, &s_temp);
553
554
  if (t_length >= 0)
589
590
 
590
591
    temp_pos=anc_buff+anc_length;
591
592
    t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
592
 
                                  keypos == temp_pos ? (unsigned char*) 0
 
593
                                  keypos == temp_pos ? (uchar*) 0
593
594
                                  : keypos,
594
595
                                  anc_pos, anc_pos,
595
596
                                  leaf_key,&s_temp);
596
597
    if (t_length > 0)
597
 
      bmove_upp((unsigned char*) temp_pos+t_length,(unsigned char*) temp_pos,
 
598
      bmove_upp((uchar*) temp_pos+t_length,(uchar*) temp_pos,
598
599
                (uint) (temp_pos-keypos));
599
600
    else
600
601
      memcpy(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
606
607
      memcpy(leaf_buff+2, half_pos - nod_flag, nod_flag);
607
608
    if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
608
609
      goto err;
609
 
    t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (unsigned char*) 0,
610
 
                                  (unsigned char*) 0, (unsigned char*) 0, leaf_key, &s_temp);
 
610
    t_length=(*keyinfo->pack_key)(keyinfo,nod_flag, (uchar*) 0,
 
611
                                  (uchar*) 0, (uchar*) 0, leaf_key, &s_temp);
611
612
    length=(uint) ((buff+buff_length)-half_pos);
612
613
    memcpy(leaf_buff + p_length + t_length, half_pos, length);
613
614
    (*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
632
633
          returns how many chars was removed or 0 on error
633
634
        */
634
635
 
635
 
static uint32_t remove_key(MI_KEYDEF *keyinfo, uint32_t nod_flag,
636
 
                       unsigned char *keypos,   /* Where key starts */
637
 
                       unsigned char *lastkey,  /* key to be removed */
638
 
                       unsigned char *page_end, /* End of page */
 
636
static uint remove_key(MI_KEYDEF *keyinfo, uint nod_flag,
 
637
                       uchar *keypos,   /* Where key starts */
 
638
                       uchar *lastkey,  /* key to be removed */
 
639
                       uchar *page_end, /* End of page */
639
640
                       my_off_t *next_block)    /* ptr to next block */
640
641
{
641
642
  int s_length;
642
 
  unsigned char *start;
 
643
  uchar *start;
643
644
 
644
645
  start=keypos;
645
646
  if (!(keyinfo->flag &
663
664
    {
664
665
      if (keyinfo->flag & HA_BINARY_PACK_KEY)
665
666
      {
666
 
        unsigned char *old_key=start;
667
 
        uint32_t next_length,prev_length,prev_pack_length;
 
667
        uchar *old_key=start;
 
668
        uint next_length,prev_length,prev_pack_length;
668
669
        get_key_length(next_length,keypos);
669
670
        get_key_pack_length(prev_length,prev_pack_length,old_key);
670
671
        if (next_length > prev_length)
683
684
        if ((keyinfo->seg->flag & HA_PACK_KEY) && *keypos & 128)
684
685
        {
685
686
          /* Next key is packed against the current one */
686
 
          uint32_t next_length,prev_length,prev_pack_length,lastkey_length,
 
687
          uint next_length,prev_length,prev_pack_length,lastkey_length,
687
688
            rest_length;
688
689
          if (keyinfo->seg[0].length >= 127)
689
690
          {
716
717
 
717
718
          if (next_length >= prev_length)
718
719
          {             /* Key after is based on deleted key */
719
 
            uint32_t pack_length,tmp;
 
720
            uint pack_length,tmp;
720
721
            bmove_upp(keypos, (lastkey+next_length),
721
722
                      tmp=(next_length-prev_length));
722
723
            rest_length+=tmp;