~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_dynrec.c

Removed/replaced DBUG symbols and TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
 
64
64
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size)
65
65
{
66
 
  DBUG_ENTER("mi_dynmap_file");
67
66
  if (size > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
68
67
  {
69
 
    DBUG_PRINT("warning", ("File is too large for mmap"));
70
 
    DBUG_RETURN(1);
 
68
    return(1);
71
69
  }
72
70
  /*
73
71
    I wonder if it is good to use MAP_NORESERVE. From the Linux man page:
86
84
  if (info->s->file_map == (uchar*) MAP_FAILED)
87
85
  {
88
86
    info->s->file_map= NULL;
89
 
    DBUG_RETURN(1);
 
87
    return(1);
90
88
  }
91
89
#if defined(HAVE_MADVISE)
92
90
  madvise((char*) info->s->file_map, size, MADV_RANDOM);
93
91
#endif
94
92
  info->s->mmaped_length= size;
95
 
  DBUG_RETURN(0);
 
93
  return(0);
96
94
}
97
95
 
98
96
 
136
134
size_t mi_mmap_pread(MI_INFO *info, uchar *Buffer,
137
135
                    size_t Count, my_off_t offset, myf MyFlags)
138
136
{
139
 
  DBUG_PRINT("info", ("mi_read with mmap %d\n", info->dfile));
140
137
  if (info->s->concurrent_insert)
141
138
    rw_rdlock(&info->s->mmap_lock);
142
139
 
191
188
size_t mi_mmap_pwrite(MI_INFO *info, const uchar *Buffer,
192
189
                      size_t Count, my_off_t offset, myf MyFlags)
193
190
{
194
 
  DBUG_PRINT("info", ("mi_write with mmap %d\n", info->dfile));
195
191
  if (info->s->concurrent_insert)
196
192
    rw_rdlock(&info->s->mmap_lock);
197
193
 
265
261
  }
266
262
  reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
267
263
                           record);
268
 
  DBUG_PRINT("info",("reclength: %lu  reclength2: %lu",
269
 
                     reclength, reclength2));
270
 
  DBUG_ASSERT(reclength2 <= reclength);
 
264
  assert(reclength2 <= reclength);
271
265
  error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
272
266
                             reclength2);
273
267
  my_afree(rec_buff);
321
315
  int flag;
322
316
  ulong length;
323
317
  my_off_t filepos;
324
 
  DBUG_ENTER("write_dynamic_record");
325
318
 
326
319
  flag=0;
327
320
 
343
336
        reclength + MI_MAX_DYN_BLOCK_HEADER)
344
337
    {
345
338
      my_errno=HA_ERR_RECORD_FILE_FULL;
346
 
      DBUG_RETURN(1);
 
339
      return(1);
347
340
    }
348
341
  }
349
342
 
358
351
      goto err;
359
352
  } while (reclength);
360
353
 
361
 
  DBUG_RETURN(0);
 
354
  return(0);
362
355
err:
363
 
  DBUG_RETURN(1);
 
356
  return(1);
364
357
}
365
358
 
366
359
 
373
366
{
374
367
  MI_BLOCK_INFO block_info;
375
368
  ulong tmp;
376
 
  DBUG_ENTER("_mi_find_writepos");
377
369
 
378
370
  if (info->s->state.dellink != HA_OFFSET_ERROR &&
379
371
      !info->append_insert_at_end)
385
377
    if (!(_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink) &
386
378
           BLOCK_DELETED))
387
379
    {
388
 
      DBUG_PRINT("error",("Delete link crashed"));
389
380
      my_errno=HA_ERR_WRONG_IN_RECORD;
390
 
      DBUG_RETURN(-1);
 
381
      return(-1);
391
382
    }
392
383
    info->s->state.dellink=block_info.next_filepos;
393
384
    info->state->del--;
408
399
        (info->s->base.max_data_file_length - tmp))
409
400
    {
410
401
      my_errno=HA_ERR_RECORD_FILE_FULL;
411
 
      DBUG_RETURN(-1);
 
402
      return(-1);
412
403
    }
413
404
    if (tmp > MI_MAX_BLOCK_LENGTH)
414
405
      tmp=MI_MAX_BLOCK_LENGTH;
417
408
    info->s->state.split++;
418
409
    info->update|=HA_STATE_WRITE_AT_END;
419
410
  }
420
 
  DBUG_RETURN(0);
 
411
  return(0);
421
412
} /* _mi_find_writepos */
422
413
 
423
414
 
430
421
 
431
422
static my_bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
432
423
{
433
 
  DBUG_ENTER("unlink_deleted_block");
434
424
  if (block_info->filepos == info->s->state.dellink)
435
425
  {
436
426
    /* First deleted block;  We can just use this ! */
443
433
    /* Unlink block from the previous block */
444
434
    if (!(_mi_get_block_info(&tmp,info->dfile,block_info->prev_filepos)
445
435
          & BLOCK_DELETED))
446
 
      DBUG_RETURN(1);                           /* Something is wrong */
 
436
      return(1);                                /* Something is wrong */
447
437
    mi_sizestore(tmp.header+4,block_info->next_filepos);
448
438
    if (info->s->file_write(info, tmp.header+4,8,
449
439
                  block_info->prev_filepos+4, MYF(MY_NABP)))
450
 
      DBUG_RETURN(1);
 
440
      return(1);
451
441
    /* Unlink block from next block */
452
442
    if (block_info->next_filepos != HA_OFFSET_ERROR)
453
443
    {
454
444
      if (!(_mi_get_block_info(&tmp,info->dfile,block_info->next_filepos)
455
445
            & BLOCK_DELETED))
456
 
        DBUG_RETURN(1);                         /* Something is wrong */
 
446
        return(1);                              /* Something is wrong */
457
447
      mi_sizestore(tmp.header+12,block_info->prev_filepos);
458
448
      if (info->s->file_write(info, tmp.header+12,8,
459
449
                    block_info->next_filepos+12,
460
450
                    MYF(MY_NABP)))
461
 
        DBUG_RETURN(1);
 
451
        return(1);
462
452
    }
463
453
  }
464
454
  /* We now have one less deleted block */
473
463
  */
474
464
  if (info->nextpos == block_info->filepos)
475
465
    info->nextpos+=block_info->block_len;
476
 
  DBUG_RETURN(0);
 
466
  return(0);
477
467
}
478
468
 
479
469
 
496
486
                                       my_off_t filepos)
497
487
{
498
488
  MI_BLOCK_INFO block_info;
499
 
  DBUG_ENTER("update_backward_delete_link");
500
489
 
501
490
  if (delete_block != HA_OFFSET_ERROR)
502
491
  {
507
496
      uchar buff[8];
508
497
      mi_sizestore(buff,filepos);
509
498
      if (info->s->file_write(info,buff, 8, delete_block+12, MYF(MY_NABP)))
510
 
        DBUG_RETURN(1);                         /* Error on write */
 
499
        return(1);                              /* Error on write */
511
500
    }
512
501
    else
513
502
    {
514
503
      my_errno=HA_ERR_WRONG_IN_RECORD;
515
 
      DBUG_RETURN(1);                           /* Wrong delete link */
 
504
      return(1);                                /* Wrong delete link */
516
505
    }
517
506
  }
518
 
  DBUG_RETURN(0);
 
507
  return(0);
519
508
}
520
509
 
521
510
        /* Delete datarecord from database */
528
517
  MI_BLOCK_INFO block_info,del_block;
529
518
  int error;
530
519
  my_bool remove_next_block;
531
 
  DBUG_ENTER("delete_dynamic_record");
532
520
 
533
521
  /* First add a link from the last block to the new one */
534
522
  error= update_backward_delete_link(info, info->s->state.dellink, filepos);
544
532
        MI_MIN_BLOCK_LENGTH)
545
533
    {
546
534
      my_errno=HA_ERR_WRONG_IN_RECORD;
547
 
      DBUG_RETURN(1);
 
535
      return(1);
548
536
    }
549
537
    /* Check if next block is a delete block */
550
538
    del_block.second_read=0;
566
554
      mi_sizestore(block_info.header+12,block_info.next_filepos);
567
555
    if (info->s->file_write(info,(uchar*) block_info.header,20,filepos,
568
556
                  MYF(MY_NABP)))
569
 
      DBUG_RETURN(1);
 
557
      return(1);
570
558
    info->s->state.dellink = filepos;
571
559
    info->state->del++;
572
560
    info->state->empty+=length;
577
565
      error=1;
578
566
  } while (!(b_type & BLOCK_LAST));
579
567
 
580
 
  DBUG_RETURN(error);
 
568
  return(error);
581
569
}
582
570
 
583
571
 
595
583
  uchar *pos,*record_end;
596
584
  my_off_t  next_delete_block;
597
585
  uchar temp[MI_SPLIT_LENGTH+MI_DYN_DELETE_BLOCK_HEADER];
598
 
  DBUG_ENTER("_mi_write_part_record");
599
586
 
600
587
  next_delete_block=HA_OFFSET_ERROR;
601
588
 
689
676
    }
690
677
    length=       *reclength+head_length;       /* Write only what is needed */
691
678
  }
692
 
  DBUG_DUMP("header",(uchar*) temp,head_length);
693
679
 
694
680
        /* Make a long block for one write */
695
681
  record_end= *record+length-head_length;
764
750
      goto err;
765
751
  }
766
752
 
767
 
  DBUG_RETURN(0);
 
753
  return(0);
768
754
err:
769
 
  DBUG_PRINT("exit",("errno: %d",my_errno));
770
 
  DBUG_RETURN(1);
 
755
  return(1);
771
756
} /*_mi_write_part_record */
772
757
 
773
758
 
780
765
  uint error;
781
766
  ulong length;
782
767
  MI_BLOCK_INFO block_info;
783
 
  DBUG_ENTER("update_dynamic_record");
784
768
 
785
769
  flag=block_info.second_read=0;
786
770
  /*
806
790
    if ((error=_mi_get_block_info(&block_info,info->dfile,filepos))
807
791
        & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | BLOCK_FATAL_ERROR))
808
792
    {
809
 
      DBUG_PRINT("error",("Got wrong block info"));
810
793
      if (!(error & BLOCK_FATAL_ERROR))
811
794
        my_errno=HA_ERR_WRONG_IN_RECORD;
812
795
      goto err;
837
820
          & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
838
821
             BLOCK_FATAL_ERROR))
839
822
      {
840
 
        DBUG_PRINT("error",("Got wrong block info"));
841
823
        if (!(error & BLOCK_FATAL_ERROR))
842
824
          my_errno=HA_ERR_WRONG_IN_RECORD;
843
825
        goto err;
856
838
            info->s->base.max_data_file_length-tmp)
857
839
        {
858
840
          /* extend file */
859
 
          DBUG_PRINT("info",("Extending file with %d bytes",tmp));
860
841
          if (info->nextpos == info->state->data_file_length)
861
842
            info->nextpos+= tmp;
862
843
          info->state->data_file_length+= tmp;
879
860
              BLOCK_DELETED)
880
861
          {
881
862
            /* Use; Unlink it and extend the current block */
882
 
            DBUG_PRINT("info",("Extending current block"));
883
863
            if (unlink_deleted_block(info,&del_block))
884
864
              goto err;
885
865
            if ((length+=del_block.block_len) > MI_MAX_BLOCK_LENGTH)
895
875
 
896
876
              if (update_backward_delete_link(info, info->s->state.dellink,
897
877
                                              next_pos))
898
 
                DBUG_RETURN(1);
 
878
                return(1);
899
879
 
900
880
              /* create delete link for data that didn't fit into the page */
901
881
              del_block.header[0]=0;
904
884
              bfill(del_block.header+12,8,255);
905
885
              if (info->s->file_write(info,(uchar*) del_block.header,20, next_pos,
906
886
                            MYF(MY_NABP)))
907
 
                DBUG_RETURN(1);
 
887
                return(1);
908
888
              info->s->state.dellink= next_pos;
909
889
              info->s->state.split++;
910
890
              info->state->del++;
933
913
  if (block_info.next_filepos != HA_OFFSET_ERROR)
934
914
    if (delete_dynamic_record(info,block_info.next_filepos,1))
935
915
      goto err;
936
 
  DBUG_RETURN(0);
 
916
  return(0);
937
917
err:
938
 
  DBUG_RETURN(1);
 
918
  return(1);
939
919
}
940
920
 
941
921
 
949
929
  enum en_fieldtype type;
950
930
  register MI_COLUMNDEF *rec;
951
931
  MI_BLOB       *blob;
952
 
  DBUG_ENTER("_mi_rec_pack");
953
932
 
954
933
  flag=0 ; bit=1;
955
934
  startpos=packpos=to; to+= info->s->base.pack_bits; blob=info->blobs;
1056
1035
    *packpos= (uchar) flag;
1057
1036
  if (info->s->calc_checksum)
1058
1037
    *to++= (uchar) info->checksum;
1059
 
  DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
1060
 
  DBUG_RETURN((uint) (to-startpos));
 
1038
  return((uint) (to-startpos));
1061
1039
} /* _mi_rec_pack */
1062
1040
 
1063
1041
 
1074
1052
  uchar         *pos,*end,*packpos,*to;
1075
1053
  enum en_fieldtype type;
1076
1054
  register MI_COLUMNDEF *rec;
1077
 
  DBUG_ENTER("_mi_rec_check");
1078
1055
 
1079
1056
  packpos=rec_buff; to= rec_buff+info->s->base.pack_bits;
1080
1057
  rec=info->s->rec;
1176
1153
    goto err;
1177
1154
  if (with_checksum && ((uchar) info->checksum != (uchar) *to))
1178
1155
  {
1179
 
    DBUG_PRINT("error",("wrong checksum for row"));
1180
1156
    goto err;
1181
1157
  }
1182
 
  DBUG_RETURN(0);
 
1158
  return(0);
1183
1159
 
1184
1160
err:
1185
 
  DBUG_RETURN(1);
 
1161
  return(1);
1186
1162
}
1187
1163
 
1188
1164
 
1198
1174
  enum en_fieldtype type;
1199
1175
  uchar *from_end,*to_end,*packpos;
1200
1176
  register MI_COLUMNDEF *rec,*end_field;
1201
 
  DBUG_ENTER("_mi_rec_unpack");
1202
1177
 
1203
1178
  to_end=to + info->s->base.reclength;
1204
1179
  from_end=from+found_length;
1314
1289
  if (info->s->calc_checksum)
1315
1290
    from++;
1316
1291
  if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
1317
 
    DBUG_RETURN(found_length);
 
1292
    return(found_length);
1318
1293
 
1319
1294
err:
1320
1295
  my_errno= HA_ERR_WRONG_IN_RECORD;
1321
 
  DBUG_PRINT("error",("to_end: 0x%lx -> 0x%lx  from_end: 0x%lx -> 0x%lx",
1322
 
                      (long) to, (long) to_end, (long) from, (long) from_end));
1323
 
  DBUG_DUMP("from",(uchar*) info->rec_buff,info->s->base.min_pack_length);
1324
 
  DBUG_RETURN(MY_FILE_ERROR);
 
1296
  return(MY_FILE_ERROR);
1325
1297
} /* _mi_rec_unpack */
1326
1298
 
1327
1299
 
1421
1393
  uchar *to= NULL;
1422
1394
  MI_BLOCK_INFO block_info;
1423
1395
  File file;
1424
 
  DBUG_ENTER("mi_read_dynamic_record");
1425
1396
 
1426
1397
  if (filepos != HA_OFFSET_ERROR)
1427
1398
  {
1501
1472
 
1502
1473
    info->update|= HA_STATE_AKTIV;      /* We have a aktive record */
1503
1474
    fast_mi_writeinfo(info);
1504
 
    DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
 
1475
    return(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
1505
1476
                MY_FILE_ERROR ? 0 : -1);
1506
1477
  }
1507
1478
  fast_mi_writeinfo(info);
1508
 
  DBUG_RETURN(-1);                      /* Wrong data to read */
 
1479
  return(-1);                   /* Wrong data to read */
1509
1480
 
1510
1481
panic:
1511
1482
  my_errno=HA_ERR_WRONG_IN_RECORD;
1512
1483
err:
1513
1484
  VOID(_mi_writeinfo(info,0));
1514
 
  DBUG_RETURN(-1);
 
1485
  return(-1);
1515
1486
}
1516
1487
 
1517
1488
        /* compare unique constraint between stored rows */
1521
1492
{
1522
1493
  uchar *rec_buff,*old_record;
1523
1494
  int error;
1524
 
  DBUG_ENTER("_mi_cmp_dynamic_unique");
1525
1495
 
1526
1496
  if (!(old_record=my_alloca(info->s->base.reclength)))
1527
 
    DBUG_RETURN(1);
 
1497
    return(1);
1528
1498
 
1529
1499
  /* Don't let the compare destroy blobs that may be in use */
1530
1500
  rec_buff=info->rec_buff;
1539
1509
    info->rec_buff=rec_buff;
1540
1510
  }
1541
1511
  my_afree(old_record);
1542
 
  DBUG_RETURN(error);
 
1512
  return(error);
1543
1513
}
1544
1514
 
1545
1515
 
1551
1521
  my_off_t filepos;
1552
1522
  uchar *buffer;
1553
1523
  MI_BLOCK_INFO block_info;
1554
 
  DBUG_ENTER("_mi_cmp_dynamic_record");
1555
1524
 
1556
1525
  if (info->opt_flag & WRITE_CACHE_USED)
1557
1526
  {
1558
1527
    info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
1559
1528
    if (flush_io_cache(&info->rec_cache))
1560
 
      DBUG_RETURN(-1);
 
1529
      return(-1);
1561
1530
  }
1562
1531
  info->rec_cache.seek_not_done=1;
1563
1532
 
1570
1539
    {
1571
1540
      if (!(buffer=(uchar*) my_alloca(info->s->base.pack_reclength+
1572
1541
                                     _my_calc_total_blob_length(info,record))))
1573
 
        DBUG_RETURN(-1);
 
1542
        return(-1);
1574
1543
    }
1575
1544
    reclength=_mi_rec_pack(info,buffer,record);
1576
1545
    record= buffer;
1617
1586
err:
1618
1587
  if (buffer != info->rec_buff)
1619
1588
    my_afree((uchar*) buffer);
1620
 
  DBUG_RETURN(my_errno);
 
1589
  return(my_errno);
1621
1590
}
1622
1591
 
1623
1592
 
1628
1597
{
1629
1598
  uint next_length;
1630
1599
  uchar temp_buff[IO_SIZE*2];
1631
 
  DBUG_ENTER("_mi_cmp_buffer");
1632
1600
 
1633
1601
  next_length= IO_SIZE*2 - (uint) (filepos & (IO_SIZE-1));
1634
1602
 
1644
1612
  }
1645
1613
  if (my_pread(file,temp_buff,length,filepos,MYF(MY_NABP)))
1646
1614
    goto err;
1647
 
  DBUG_RETURN(memcmp(buff,temp_buff,length));
 
1615
  return(memcmp(buff,temp_buff,length));
1648
1616
err:
1649
 
  DBUG_RETURN(1);
 
1617
  return(1);
1650
1618
}
1651
1619
 
1652
1620
 
1693
1661
  uchar *to= NULL;
1694
1662
  MI_BLOCK_INFO block_info;
1695
1663
  MYISAM_SHARE *share=info->s;
1696
 
  DBUG_ENTER("_mi_read_rnd_dynamic_record");
1697
1664
 
1698
1665
  info_read=0;
1699
1666
 
1704
1671
    {
1705
1672
      if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
1706
1673
                  MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
1707
 
        DBUG_RETURN(my_errno);
 
1674
        return(my_errno);
1708
1675
    }
1709
1676
#else
1710
1677
    info->tmp_lock_type=F_RDLCK;
1747
1714
      if (info->opt_flag & WRITE_CACHE_USED &&
1748
1715
          info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
1749
1716
          flush_io_cache(&info->rec_cache))
1750
 
        DBUG_RETURN(my_errno);
 
1717
        return(my_errno);
1751
1718
      info->rec_cache.seek_not_done=1;
1752
1719
      b_type=_mi_get_block_info(&block_info,info->dfile,filepos);
1753
1720
    }
1850
1817
  fast_mi_writeinfo(info);
1851
1818
  if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
1852
1819
      MY_FILE_ERROR)
1853
 
    DBUG_RETURN(0);
1854
 
  DBUG_RETURN(my_errno);                        /* Wrong record */
 
1820
    return(0);
 
1821
  return(my_errno);                     /* Wrong record */
1855
1822
 
1856
1823
panic:
1857
1824
  my_errno=HA_ERR_WRONG_IN_RECORD;              /* Something is fatal wrong */
1858
1825
err:
1859
1826
  save_errno=my_errno;
1860
1827
  VOID(_mi_writeinfo(info,0));
1861
 
  DBUG_RETURN(my_errno=save_errno);
 
1828
  return(my_errno=save_errno);
1862
1829
}
1863
1830
 
1864
1831
 
1881
1848
        sizeof(info->header))
1882
1849
      goto err;
1883
1850
  }
1884
 
  DBUG_DUMP("header",header,MI_BLOCK_INFO_HEADER_LENGTH);
1885
1851
  if (info->second_read)
1886
1852
  {
1887
1853
    if (info->header[0] <= 6 || info->header[0] == 13)