~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_write.c

  • Committer: Monty Taylor
  • Date: 2008-07-16 19:10:24 UTC
  • mfrom: (51.1.127 remove-dbug)
  • mto: This revision was merged to the branch mainline in revision 176.
  • Revision ID: monty@inaugust.com-20080716191024-prjgoh7fbri7rx26
MergedĀ fromĀ remove-dbug.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
  my_off_t filepos;
48
48
  uchar *buff;
49
49
  my_bool lock_tree= share->concurrent_insert;
50
 
  DBUG_ENTER("mi_write");
51
 
  DBUG_PRINT("enter",("isam: %d  data: %d",info->s->kfile,info->dfile));
52
50
 
53
 
  DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
54
 
                  mi_print_error(info->s, HA_ERR_CRASHED);
55
 
                  DBUG_RETURN(my_errno= HA_ERR_CRASHED););
56
51
  if (share->options & HA_OPTION_READ_ONLY_DATA)
57
52
  {
58
 
    DBUG_RETURN(my_errno=EACCES);
 
53
    return(my_errno=EACCES);
59
54
  }
60
55
  if (_mi_readinfo(info,F_WRLCK,1))
61
 
    DBUG_RETURN(my_errno);
 
56
    return(my_errno);
62
57
  filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
63
58
             !info->append_insert_at_end) ?
64
59
            share->state.dellink :
109
104
        {
110
105
          if (local_lock_tree)
111
106
            rw_unlock(&share->key_root_lock[i]);
112
 
          DBUG_PRINT("error",("Got error: %d on write",my_errno));
113
107
          goto err;
114
108
        }
115
109
      }
140
134
  VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
141
135
  if (info->invalidator != 0)
142
136
  {
143
 
    DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
144
137
    (*info->invalidator)(info->filename);
145
138
    info->invalidator=0;
146
139
  }
156
149
  if (share->is_log_table)
157
150
    mi_update_status((void*) info);
158
151
 
159
 
  DBUG_RETURN(0);
 
152
  return(0);
160
153
 
161
154
err:
162
155
  save_errno=my_errno;
204
197
  save_errno=my_errno;
205
198
  myisam_log_record(MI_LOG_WRITE,info,record,filepos,my_errno);
206
199
  VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
207
 
  DBUG_RETURN(my_errno=save_errno);
 
200
  return(my_errno=save_errno);
208
201
} /* mi_write */
209
202
 
210
203
 
212
205
 
213
206
int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
214
207
{
215
 
  DBUG_ENTER("_mi_ck_write");
216
 
 
217
208
  if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr]))
218
209
  {
219
 
    DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length));
 
210
    return(_mi_ck_write_tree(info, keynr, key, key_length));
220
211
  }
221
212
  else
222
213
  {
223
 
    DBUG_RETURN(_mi_ck_write_btree(info, keynr, key, key_length));
 
214
    return(_mi_ck_write_btree(info, keynr, key, key_length));
224
215
  }
225
216
} /* _mi_ck_write */
226
217
 
236
227
  uint comp_flag;
237
228
  MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
238
229
  my_off_t  *root=&info->s->state.key_root[keynr];
239
 
  DBUG_ENTER("_mi_ck_write_btree");
240
230
 
241
231
  if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
242
232
    comp_flag=SEARCH_BIGGER;                    /* Put after same key */
251
241
 
252
242
  error=_mi_ck_real_write_btree(info, keyinfo, key, key_length,
253
243
                                root, comp_flag);
254
 
  DBUG_RETURN(error);
 
244
  return(error);
255
245
} /* _mi_ck_write_btree */
256
246
 
257
247
int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo,
258
248
    uchar *key, uint key_length, my_off_t *root, uint comp_flag)
259
249
{
260
250
  int error;
261
 
  DBUG_ENTER("_mi_ck_real_write_btree");
262
251
  /* key_length parameter is used only if comp_flag is SEARCH_FIND */
263
252
  if (*root == HA_OFFSET_ERROR ||
264
253
      (error=w_search(info, keyinfo, comp_flag, key, key_length,
265
254
                      *root, (uchar *) 0, (uchar*) 0,
266
255
                      (my_off_t) 0, 1)) > 0)
267
256
    error=_mi_enlarge_root(info,keyinfo,key,root);
268
 
  DBUG_RETURN(error);
 
257
  return(error);
269
258
} /* _mi_ck_real_write_btree */
270
259
 
271
260
 
277
266
  uint t_length,nod_flag;
278
267
  MI_KEY_PARAM s_temp;
279
268
  MYISAM_SHARE *share=info->s;
280
 
  DBUG_ENTER("_mi_enlarge_root");
281
269
 
282
270
  nod_flag= (*root != HA_OFFSET_ERROR) ?  share->base.key_reflength : 0;
283
271
  _mi_kpointer(info,info->buff+2,*root); /* if nod */
288
276
  info->buff_used=info->page_changed=1;         /* info->buff is used */
289
277
  if ((*root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
290
278
      _mi_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
291
 
    DBUG_RETURN(-1);
292
 
  DBUG_RETURN(0);
 
279
    return(-1);
 
280
  return(0);
293
281
} /* _mi_enlarge_root */
294
282
 
295
283
 
311
299
  uchar keybuff[MI_MAX_KEY_BUFF];
312
300
  my_bool was_last_key;
313
301
  my_off_t next_page, dupp_key_pos;
314
 
  DBUG_ENTER("w_search");
315
 
  DBUG_PRINT("enter",("page: %ld", (long) page));
316
302
 
317
303
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
318
304
  if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
319
305
                                      MI_MAX_KEY_BUFF*2)))
320
 
    DBUG_RETURN(-1);
 
306
    return(-1);
321
307
  if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
322
308
    goto err;
323
309
 
338
324
      info->dupp_key_pos= dupp_key_pos;
339
325
      my_afree((uchar*) temp_buff);
340
326
      my_errno=HA_ERR_FOUND_DUPP_KEY;
341
 
      DBUG_RETURN(-1);
 
327
      return(-1);
342
328
    }
343
329
  }
344
330
  if (flag == MI_FOUND_WRONG_KEY)
345
 
    DBUG_RETURN(-1);
 
331
    return(-1);
346
332
  if (!was_last_key)
347
333
    insert_last=0;
348
334
  next_page=_mi_kpos(nod_flag,keypos);
356
342
      goto err;
357
343
  }
358
344
  my_afree((uchar*) temp_buff);
359
 
  DBUG_RETURN(error);
 
345
  return(error);
360
346
err:
361
347
  my_afree((uchar*) temp_buff);
362
 
  DBUG_PRINT("exit",("Error: %d",my_errno));
363
 
  DBUG_RETURN (-1);
 
348
  return (-1);
364
349
} /* w_search */
365
350
 
366
351
 
398
383
  int t_length;
399
384
  uchar *endpos, *prev_key;
400
385
  MI_KEY_PARAM s_temp;
401
 
  DBUG_ENTER("_mi_insert");
402
 
  DBUG_PRINT("enter",("key_pos: 0x%lx", (long) key_pos));
403
 
  DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,USE_WHOLE_KEY););
404
386
 
405
387
  nod_flag=mi_test_if_nod(anc_buff);
406
388
  a_length=mi_getint(anc_buff);
410
392
                                (key_pos == endpos ? (uchar*) 0 : key_pos),
411
393
                                prev_key, prev_key,
412
394
                                key,&s_temp);
413
 
#ifndef DBUG_OFF
414
 
  if (key_pos != anc_buff+2+nod_flag && (keyinfo->flag &
415
 
                                         (HA_BINARY_PACK_KEY | HA_PACK_KEY)))
416
 
  {
417
 
    DBUG_DUMP("prev_key",(uchar*) key_buff,_mi_keylength(keyinfo,key_buff));
418
 
  }
419
 
  if (keyinfo->flag & HA_PACK_KEY)
420
 
  {
421
 
    DBUG_PRINT("test",("t_length: %d  ref_len: %d",
422
 
                       t_length,s_temp.ref_length));
423
 
    DBUG_PRINT("test",("n_ref_len: %d  n_length: %d  key_pos: 0x%lx",
424
 
                       s_temp.n_ref_length,s_temp.n_length, (long) s_temp.key));
425
 
  }
426
 
#endif
 
395
 
427
396
  if (t_length > 0)
428
397
  {
429
398
    if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
430
399
    {
431
400
      mi_print_error(info->s, HA_ERR_CRASHED);
432
401
      my_errno=HA_ERR_CRASHED;
433
 
      DBUG_RETURN(-1);
 
402
      return(-1);
434
403
    }
435
404
    bmove_upp((uchar*) endpos+t_length,(uchar*) endpos,(uint) (endpos-key_pos));
436
405
  }
440
409
    {
441
410
      mi_print_error(info->s, HA_ERR_CRASHED);
442
411
      my_errno=HA_ERR_CRASHED;
443
 
      DBUG_RETURN(-1);
 
412
      return(-1);
444
413
    }
445
414
    bmove(key_pos,key_pos-t_length,(uint) (endpos-key_pos)+t_length);
446
415
  }
449
418
  mi_putint(anc_buff,a_length,nod_flag);
450
419
  if (a_length <= keyinfo->block_length)
451
420
  {
452
 
    DBUG_RETURN(0);                             /* There is room on page */
 
421
    return(0);                          /* There is room on page */
453
422
  }
454
423
  /* Page is full */
455
424
  if (nod_flag)
456
425
    insert_last=0;
457
426
  if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
458
427
      father_buff && !insert_last)
459
 
    DBUG_RETURN(_mi_balance_page(info,keyinfo,key,anc_buff,father_buff,
 
428
    return(_mi_balance_page(info,keyinfo,key,anc_buff,father_buff,
460
429
                                 father_key_pos,father_page));
461
 
  DBUG_RETURN(_mi_split_page(info,keyinfo,key,anc_buff,key_buff, insert_last));
 
430
  return(_mi_split_page(info,keyinfo,key,anc_buff,key_buff, insert_last));
462
431
} /* _mi_insert */
463
432
 
464
433
 
472
441
  uchar *key_pos,*pos, *after_key= NULL;
473
442
  my_off_t new_pos;
474
443
  MI_KEY_PARAM s_temp;
475
 
  DBUG_ENTER("mi_split_page");
476
 
  DBUG_DUMP("buff",(uchar*) buff,mi_getint(buff));
477
444
 
478
445
  if (info->s->keyinfo+info->lastinx == keyinfo)
479
446
    info->page_changed=1;                       /* Info->buff is used */
486
453
    key_pos=_mi_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length,
487
454
                              &after_key);
488
455
  if (!key_pos)
489
 
    DBUG_RETURN(-1);
 
456
    return(-1);
490
457
 
491
458
  length=(uint) (key_pos-buff);
492
459
  a_length=mi_getint(buff);
495
462
  key_pos=after_key;
496
463
  if (nod_flag)
497
464
  {
498
 
    DBUG_PRINT("test",("Splitting nod"));
499
465
    pos=key_pos-nod_flag;
500
466
    memcpy((uchar*) info->buff+2,(uchar*) pos,(size_t) nod_flag);
501
467
  }
502
468
 
503
469
        /* Move middle item to key and pointer to new page */
504
470
  if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
505
 
    DBUG_RETURN(-1);
 
471
    return(-1);
506
472
  _mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos);
507
473
 
508
474
        /* Store new page */
509
475
  if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff))
510
 
    DBUG_RETURN(-1);
 
476
    return(-1);
511
477
 
512
478
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0,
513
479
                                (uchar*) 0, (uchar*) 0,
519
485
  mi_putint(info->buff,length+t_length+key_ref_length,nod_flag);
520
486
 
521
487
  if (_mi_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
522
 
    DBUG_RETURN(-1);
523
 
  DBUG_DUMP("key",(uchar*) key,_mi_keylength(keyinfo,key));
524
 
  DBUG_RETURN(2);                               /* Middle key up */
 
488
    return(-1);
 
489
  return(2);                            /* Middle key up */
525
490
} /* _mi_split_page */
526
491
 
527
492
 
539
504
{
540
505
  uint keys,length,key_ref_length;
541
506
  uchar *end,*lastpos;
542
 
  DBUG_ENTER("_mi_find_half_pos");
543
507
 
544
508
  key_ref_length=2+nod_flag;
545
509
  length=mi_getint(page)-key_ref_length;
554
518
    end=page+keys*key_ref_length;
555
519
    *after_key=end+key_ref_length;
556
520
    memcpy(key,end,key_ref_length);
557
 
    DBUG_RETURN(end);
 
521
    return(end);
558
522
  }
559
523
 
560
524
  end=page+length/2-key_ref_length;             /* This is aprox. half */
563
527
  {
564
528
    lastpos=page;
565
529
    if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key)))
566
 
      DBUG_RETURN(0);
 
530
      return(0);
567
531
  } while (page < end);
568
532
  *return_key_length=length;
569
533
  *after_key=page;
570
 
  DBUG_PRINT("exit",("returns: 0x%lx  page: 0x%lx  half: 0x%lx",
571
 
                     (long) lastpos, (long) page, (long) end));
572
 
  DBUG_RETURN(lastpos);
 
534
  return(lastpos);
573
535
} /* _mi_find_half_pos */
574
536
 
575
537
 
580
542
        */
581
543
 
582
544
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
583
 
                                uchar *key, uint *return_key_length,
584
 
                                uchar **after_key)
 
545
                                uchar *key, uint *return_key_length,
 
546
                                uchar **after_key)
585
547
{
586
 
  uint keys, length, last_length=0, key_ref_length;
 
548
  uint keys;
 
549
  uint length;
 
550
  uint last_length= 0;
 
551
  uint key_ref_length;
587
552
  uchar *end, *lastpos, *prevpos= NULL;
588
553
  uchar key_buff[MI_MAX_KEY_BUFF];
589
 
  DBUG_ENTER("_mi_find_last_pos");
590
554
 
591
555
  key_ref_length=2;
592
556
  length=mi_getint(page)-key_ref_length;
600
564
    end=page+keys*length;
601
565
    *after_key=end+length;
602
566
    memcpy(key,end,length);
603
 
    DBUG_RETURN(end);
 
567
    return(end);
604
568
  }
605
569
 
606
570
  end= page + length - key_ref_length;
616
580
    {
617
581
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
618
582
      my_errno=HA_ERR_CRASHED;
619
 
      DBUG_RETURN(0);
 
583
      return(0);
620
584
    }
621
585
  }
622
586
  *return_key_length=last_length;
623
587
  *after_key=lastpos;
624
 
  DBUG_PRINT("exit",("returns: 0x%lx  page: 0x%lx  end: 0x%lx",
625
 
                     (long) prevpos,(long) page,(long) end));
626
 
  DBUG_RETURN(prevpos);
 
588
  return(prevpos);
627
589
} /* _mi_find_last_pos */
628
590
 
629
591
 
641
603
  uchar *pos,*buff,*extra_buff;
642
604
  my_off_t next_page,new_pos;
643
605
  uchar tmp_part_key[MI_MAX_KEY_BUFF];
644
 
  DBUG_ENTER("_mi_balance_page");
645
606
 
646
607
  k_length=keyinfo->keylength;
647
608
  father_length=mi_getint(father_buff);
658
619
    next_page= _mi_kpos(info->s->base.key_reflength,
659
620
                        father_key_pos+father_keylength);
660
621
    buff=info->buff;
661
 
    DBUG_PRINT("test",("use right page: %lu", (ulong) next_page));
662
622
  }
663
623
  else
664
624
  {
667
627
    next_page= _mi_kpos(info->s->base.key_reflength,father_key_pos);
668
628
                                        /* Fix that curr_buff is to left */
669
629
    buff=curr_buff; curr_buff=info->buff;
670
 
    DBUG_PRINT("test",("use left page: %lu", (ulong) next_page));
671
630
  }                                     /* father_key_pos ptr to parting key */
672
631
 
673
632
  if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
674
633
    goto err;
675
 
  DBUG_DUMP("next",(uchar*) info->buff,mi_getint(info->buff));
676
634
 
677
635
        /* Test if there is room to share keys */
678
636
 
713
671
    if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
714
672
        _mi_write_keypage(info,keyinfo,father_page,DFLT_INIT_HITS,father_buff))
715
673
      goto err;
716
 
    DBUG_RETURN(0);
 
674
    return(0);
717
675
  }
718
676
 
719
677
        /* curr_buff[] and buff[] are full, lets split and make new nod */
724
682
    new_left_length-=curr_keylength;
725
683
  extra_length=nod_flag+left_length+right_length-
726
684
    new_left_length-new_right_length-curr_keylength;
727
 
  DBUG_PRINT("info",("left_length: %d  right_length: %d  new_left_length: %d  new_right_length: %d  extra_length: %d",
728
 
                     left_length, right_length,
729
 
                     new_left_length, new_right_length,
730
 
                     extra_length));
731
685
  mi_putint(curr_buff,new_left_length,nod_flag);
732
686
  mi_putint(buff,new_right_length,nod_flag);
733
687
  mi_putint(extra_buff,extra_length+2,nod_flag);
760
714
                        DFLT_INIT_HITS,extra_buff))
761
715
    goto err;
762
716
 
763
 
  DBUG_RETURN(1);                               /* Middle key up */
 
717
  return(1);                            /* Middle key up */
764
718
 
765
719
err:
766
 
  DBUG_RETURN(-1);
 
720
  return(-1);
767
721
} /* _mi_balance_page */
768
722
 
769
723
/**********************************************************************
779
733
                      uint key_length)
780
734
{
781
735
  int error;
782
 
  DBUG_ENTER("_mi_ck_write_tree");
783
736
 
784
737
  error= tree_insert(&info->bulk_insert[keynr], key,
785
738
         key_length + info->s->rec_reflength,
786
739
         info->bulk_insert[keynr].custom_arg) ? 0 : HA_ERR_OUT_OF_MEM ;
787
740
 
788
 
  DBUG_RETURN(error);
 
741
  return(error);
789
742
} /* _mi_ck_write_tree */
790
743
 
791
744
 
840
793
  bulk_insert_param *params;
841
794
  uint i, num_keys, total_keylength;
842
795
  uint64_t key_map;
843
 
  DBUG_ENTER("_mi_init_bulk_insert");
844
 
  DBUG_PRINT("enter",("cache_size: %lu", cache_size));
845
796
 
846
 
  DBUG_ASSERT(!info->bulk_insert &&
 
797
  assert(!info->bulk_insert &&
847
798
              (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT));
848
799
 
849
800
  mi_clear_all_keys_active(key_map);
860
811
 
861
812
  if (num_keys==0 ||
862
813
      num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size)
863
 
    DBUG_RETURN(0);
 
814
    return(0);
864
815
 
865
816
  if (rows && rows*total_keylength < cache_size)
866
817
    cache_size= (ulong)rows;
872
823
               sizeof(bulk_insert_param)*num_keys),MYF(0));
873
824
 
874
825
  if (!info->bulk_insert)
875
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
826
    return(HA_ERR_OUT_OF_MEM);
876
827
 
877
828
  params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
878
829
  for (i=0 ; i < share->base.keys ; i++)
892
843
     info->bulk_insert[i].root=0;
893
844
  }
894
845
 
895
 
  DBUG_RETURN(0);
 
846
  return(0);
896
847
}
897
848
 
898
849
void mi_flush_bulk_insert(MI_INFO *info, uint inx)