~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_delete.c

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

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