~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_dynrec.cc

  • Committer: Daniel Nichter
  • Date: 2011-10-23 16:01:37 UTC
  • mto: This revision was merged to the branch mainline in revision 2448.
  • Revision ID: daniel@percona.com-20111023160137-7ac3blgz8z4tf8za
Add Administration Getting Started and Logging.  Capitalize SQL clause keywords.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/*
17
17
  Functions to handle space-packed-records and blobs
18
 
 
 
18
 
19
19
  A row may be stored in one or more linked blocks.
20
20
  The block size is between MI_MIN_BLOCK_LENGTH and MI_MAX_BLOCK_LENGTH.
21
21
  Each block is aligned on MI_DYN_ALIGN_SIZE.
23
23
  of blocks.  For the differnet block types, look at _mi_get_block_info()
24
24
*/
25
25
 
26
 
#include "myisamdef.h"
 
26
#include "myisam_priv.h"
27
27
 
28
28
#ifdef HAVE_SYS_TYPES
29
29
#include <sys/types.h>
32
32
#include <sys/mman.h>
33
33
#endif
34
34
#include <drizzled/util/test.h>
 
35
#include <drizzled/error.h>
 
36
 
 
37
#include <cassert>
 
38
#include <algorithm>
 
39
 
 
40
using namespace drizzled;
 
41
using namespace std;
35
42
 
36
43
/* Enough for comparing if number is zero */
37
44
static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
38
45
 
39
46
static int write_dynamic_record(MI_INFO *info,const unsigned char *record,
40
47
                                ulong reclength);
41
 
static int _mi_find_writepos(MI_INFO *info,ulong reclength,my_off_t *filepos,
 
48
static int _mi_find_writepos(MI_INFO *info,ulong reclength,internal::my_off_t *filepos,
42
49
                             ulong *length);
43
 
static int update_dynamic_record(MI_INFO *info,my_off_t filepos,unsigned char *record,
 
50
static int update_dynamic_record(MI_INFO *info,internal::my_off_t filepos,unsigned char *record,
44
51
                                 ulong reclength);
45
 
static int delete_dynamic_record(MI_INFO *info,my_off_t filepos,
 
52
static int delete_dynamic_record(MI_INFO *info,internal::my_off_t filepos,
46
53
                                 uint32_t second_read);
47
 
static int _mi_cmp_buffer(File file, const unsigned char *buff, my_off_t filepos,
 
54
static int _mi_cmp_buffer(int file, const unsigned char *buff, internal::my_off_t filepos,
48
55
                          uint32_t length);
49
56
 
50
 
/* Play it safe; We have a small stack when using threads */
51
 
#undef my_alloca
52
 
#undef my_afree
53
 
#define my_alloca(A) malloc((A))
54
 
#define my_afree(A) free((A))
55
 
 
56
57
        /* Interface function from MI_INFO */
57
58
 
58
 
#ifdef HAVE_MMAP
59
59
 
60
60
/*
61
61
  Create mmaped area for MyISAM handler
69
69
    1  error.
70
70
*/
71
71
 
72
 
bool mi_dynmap_file(MI_INFO *info, my_off_t size)
 
72
bool mi_dynmap_file(MI_INFO *info, internal::my_off_t size)
73
73
{
74
 
  if (size > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
 
74
  if (size > (internal::my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
75
75
  {
76
76
    return(1);
77
77
  }
84
84
      upon a write if no physical memory is available.
85
85
  */
86
86
  info->s->file_map= (unsigned char*)
87
 
                  my_mmap(0, (size_t)(size + MEMMAP_EXTRA_MARGIN),
88
 
                          info->s->mode==O_RDONLY ? PROT_READ :
89
 
                          PROT_READ | PROT_WRITE,
90
 
                          MAP_SHARED | MAP_NORESERVE,
91
 
                          info->dfile, 0L);
 
87
                  mmap(NULL, (size_t)(size + MEMMAP_EXTRA_MARGIN),
 
88
                       info->s->mode==O_RDONLY ? PROT_READ :
 
89
                       PROT_READ | PROT_WRITE,
 
90
                       MAP_SHARED | MAP_NORESERVE,
 
91
                       info->dfile, 0L);
92
92
  if (info->s->file_map == (unsigned char*) MAP_FAILED)
93
93
  {
94
94
    info->s->file_map= NULL;
95
95
    return(1);
96
96
  }
97
97
/* per krow we should look at removing the following code */
98
 
#if defined(HAVE_MADVISE) && !defined(TARGET_OS_SOLARIS)
 
98
#if !defined(TARGET_OS_SOLARIS)
99
99
  madvise((char*) info->s->file_map, size, MADV_RANDOM);
100
100
#endif
101
101
  info->s->mmaped_length= size;
113
113
  RETURN
114
114
*/
115
115
 
116
 
void mi_remap_file(MI_INFO *info, my_off_t size)
 
116
void mi_remap_file(MI_INFO *info, internal::my_off_t size)
117
117
{
118
118
  if (info->s->file_map)
119
119
  {
120
 
    my_munmap((char*) info->s->file_map,
121
 
              (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN);
 
120
    munmap((char*) info->s->file_map,
 
121
           (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN);
122
122
    mi_dynmap_file(info, size);
123
123
  }
124
124
}
125
 
#endif
126
125
 
127
126
 
128
127
/*
134
133
    Buffer              Input buffer
135
134
    Count               Count of bytes for read
136
135
    offset              Start position
137
 
    MyFlags             
 
136
    MyFlags
138
137
 
139
138
  RETURN
140
139
    0  ok
141
140
*/
142
141
 
143
142
size_t mi_mmap_pread(MI_INFO *info, unsigned char *Buffer,
144
 
                    size_t Count, my_off_t offset, myf MyFlags)
 
143
                    size_t Count, internal::my_off_t offset, myf MyFlags)
145
144
{
146
 
  if (info->s->concurrent_insert)
147
 
    rw_rdlock(&info->s->mmap_lock);
148
 
 
149
145
  /*
150
146
    The following test may fail in the following cases:
151
147
    - We failed to remap a memory area (fragmented memory?)
156
152
  if (info->s->mmaped_length >= offset + Count)
157
153
  {
158
154
    memcpy(Buffer, info->s->file_map + offset, Count);
159
 
    if (info->s->concurrent_insert)
160
 
      rw_unlock(&info->s->mmap_lock);
161
155
    return 0;
162
156
  }
163
157
  else
164
158
  {
165
 
    if (info->s->concurrent_insert)
166
 
      rw_unlock(&info->s->mmap_lock);
167
159
    return my_pread(info->dfile, Buffer, Count, offset, MyFlags);
168
160
  }
169
161
}
172
164
        /* wrapper for my_pread in case if mmap isn't used */
173
165
 
174
166
size_t mi_nommap_pread(MI_INFO *info, unsigned char *Buffer,
175
 
                       size_t Count, my_off_t offset, myf MyFlags)
 
167
                       size_t Count, internal::my_off_t offset, myf MyFlags)
176
168
{
177
169
  return my_pread(info->dfile, Buffer, Count, offset, MyFlags);
178
170
}
187
179
    Buffer              Output buffer
188
180
    Count               Count of bytes for write
189
181
    offset              Start position
190
 
    MyFlags             
 
182
    MyFlags
191
183
 
192
184
  RETURN
193
185
    0  ok
195
187
*/
196
188
 
197
189
size_t mi_mmap_pwrite(MI_INFO *info, const unsigned char *Buffer,
198
 
                      size_t Count, my_off_t offset, myf MyFlags)
 
190
                      size_t Count, internal::my_off_t offset, myf MyFlags)
199
191
{
200
 
  if (info->s->concurrent_insert)
201
 
    rw_rdlock(&info->s->mmap_lock);
202
192
 
203
193
  /*
204
194
    The following test may fail in the following cases:
209
199
 
210
200
  if (info->s->mmaped_length >= offset + Count)
211
201
  {
212
 
    memcpy(info->s->file_map + offset, Buffer, Count); 
213
 
    if (info->s->concurrent_insert)
214
 
      rw_unlock(&info->s->mmap_lock);
 
202
    memcpy(info->s->file_map + offset, Buffer, Count);
215
203
    return 0;
216
204
  }
217
205
  else
218
206
  {
219
207
    info->s->nonmmaped_inserts++;
220
 
    if (info->s->concurrent_insert)
221
 
      rw_unlock(&info->s->mmap_lock);
222
208
    return my_pwrite(info->dfile, Buffer, Count, offset, MyFlags);
223
209
  }
224
210
 
228
214
        /* wrapper for my_pwrite in case if mmap isn't used */
229
215
 
230
216
size_t mi_nommap_pwrite(MI_INFO *info, const unsigned char *Buffer,
231
 
                      size_t Count, my_off_t offset, myf MyFlags)
 
217
                      size_t Count, internal::my_off_t offset, myf MyFlags)
232
218
{
233
219
  return my_pwrite(info->dfile, Buffer, Count, offset, MyFlags);
234
220
}
240
226
  return (write_dynamic_record(info,info->rec_buff,reclength));
241
227
}
242
228
 
243
 
int _mi_update_dynamic_record(MI_INFO *info, my_off_t pos, const unsigned char *record)
 
229
int _mi_update_dynamic_record(MI_INFO *info, internal::my_off_t pos, const unsigned char *record)
244
230
{
245
231
  uint32_t length=_mi_rec_pack(info,info->rec_buff,record);
246
232
  return (update_dynamic_record(info,pos,info->rec_buff,length));
259
245
#ifdef NOT_USED                                 /* We now support big rows */
260
246
  if (reclength > MI_DYN_MAX_ROW_LENGTH)
261
247
  {
262
 
    my_errno=HA_ERR_TO_BIG_ROW;
 
248
    errno=HA_ERR_TO_BIG_ROW;
263
249
    return -1;
264
250
  }
265
251
#endif
266
 
  if (!(rec_buff=(unsigned char*) my_alloca(reclength)))
 
252
  if (!(rec_buff=(unsigned char*) malloc(reclength)))
267
253
  {
268
 
    my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
 
254
    errno= HA_ERR_OUT_OF_MEM;
269
255
    return(-1);
270
256
  }
271
257
  reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
273
259
  assert(reclength2 <= reclength);
274
260
  error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
275
261
                             reclength2);
276
 
  my_afree(rec_buff);
 
262
  free(rec_buff);
277
263
  return(error);
278
264
}
279
265
 
280
266
 
281
 
int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const unsigned char *record)
 
267
int _mi_update_blob_record(MI_INFO *info, internal::my_off_t pos, const unsigned char *record)
282
268
{
283
269
  unsigned char *rec_buff;
284
270
  int error;
291
277
#ifdef NOT_USED                                 /* We now support big rows */
292
278
  if (reclength > MI_DYN_MAX_ROW_LENGTH)
293
279
  {
294
 
    my_errno=HA_ERR_TO_BIG_ROW;
 
280
    errno=HA_ERR_TO_BIG_ROW;
295
281
    return -1;
296
282
  }
297
283
#endif
298
 
  if (!(rec_buff=(unsigned char*) my_alloca(reclength)))
 
284
  if (!(rec_buff=(unsigned char*) malloc(reclength)))
299
285
  {
300
 
    my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
 
286
    errno= HA_ERR_OUT_OF_MEM;
301
287
    return(-1);
302
288
  }
303
289
  reclength=_mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
305
291
  error=update_dynamic_record(info,pos,
306
292
                              rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
307
293
                              reclength);
308
 
  my_afree(rec_buff);
 
294
  free(rec_buff);
309
295
  return(error);
310
296
}
311
297
 
323
309
{
324
310
  int flag;
325
311
  ulong length;
326
 
  my_off_t filepos;
 
312
  internal::my_off_t filepos;
327
313
 
328
314
  flag=0;
329
315
 
344
330
        info->state->empty - info->state->del * MI_MAX_DYN_BLOCK_HEADER <
345
331
        reclength + MI_MAX_DYN_BLOCK_HEADER)
346
332
    {
347
 
      my_errno=HA_ERR_RECORD_FILE_FULL;
 
333
      errno=HA_ERR_RECORD_FILE_FULL;
348
334
      return(1);
349
335
    }
350
336
  }
370
356
 
371
357
static int _mi_find_writepos(MI_INFO *info,
372
358
                             ulong reclength, /* record length */
373
 
                             my_off_t *filepos, /* Return file pos */
 
359
                             internal::my_off_t *filepos, /* Return file pos */
374
360
                             ulong *length)   /* length of block at filepos */
375
361
{
376
362
  MI_BLOCK_INFO block_info;
386
372
    if (!(_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink) &
387
373
           BLOCK_DELETED))
388
374
    {
389
 
      my_errno=HA_ERR_WRONG_IN_RECORD;
 
375
      errno=HA_ERR_WRONG_IN_RECORD;
390
376
      return(-1);
391
377
    }
392
378
    info->s->state.dellink=block_info.next_filepos;
407
393
    if (info->state->data_file_length >
408
394
        (info->s->base.max_data_file_length - tmp))
409
395
    {
410
 
      my_errno=HA_ERR_RECORD_FILE_FULL;
 
396
      errno=HA_ERR_RECORD_FILE_FULL;
411
397
      return(-1);
412
398
    }
413
399
    if (tmp > MI_MAX_BLOCK_LENGTH)
491
477
    1  error.  In this case my_error is set.
492
478
*/
493
479
 
494
 
static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block,
495
 
                                       my_off_t filepos)
 
480
static int update_backward_delete_link(MI_INFO *info, internal::my_off_t delete_block,
 
481
                                       internal::my_off_t filepos)
496
482
{
497
483
  MI_BLOCK_INFO block_info;
498
484
 
509
495
    }
510
496
    else
511
497
    {
512
 
      my_errno=HA_ERR_WRONG_IN_RECORD;
 
498
      errno=HA_ERR_WRONG_IN_RECORD;
513
499
      return(1);                                /* Wrong delete link */
514
500
    }
515
501
  }
519
505
        /* Delete datarecord from database */
520
506
        /* info->rec_cache.seek_not_done is updated in cmp_record */
521
507
 
522
 
static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
 
508
static int delete_dynamic_record(MI_INFO *info, internal::my_off_t filepos,
523
509
                                 uint32_t second_read)
524
510
{
525
511
  uint32_t length,b_type;
540
526
        (length=(uint) (block_info.filepos-filepos) +block_info.block_len) <
541
527
        MI_MIN_BLOCK_LENGTH)
542
528
    {
543
 
      my_errno=HA_ERR_WRONG_IN_RECORD;
 
529
      errno=HA_ERR_WRONG_IN_RECORD;
544
530
      return(1);
545
531
    }
546
532
    /* Check if next block is a delete block */
581
567
        /* Write a block to datafile */
582
568
 
583
569
int _mi_write_part_record(MI_INFO *info,
584
 
                          my_off_t filepos,     /* points at empty block */
 
570
                          internal::my_off_t filepos,   /* points at empty block */
585
571
                          ulong length,         /* length of block */
586
 
                          my_off_t next_filepos,/* Next empty block */
 
572
                          internal::my_off_t next_filepos,/* Next empty block */
587
573
                          unsigned char **record,       /* pointer to record ptr */
588
574
                          ulong *reclength,     /* length of *record */
589
575
                          int *flag)            /* *flag == 0 if header */
590
576
{
591
577
  ulong head_length,res_length,extra_length,long_block,del_length;
592
578
  unsigned char *pos,*record_end;
593
 
  my_off_t  next_delete_block;
 
579
  internal::my_off_t  next_delete_block;
594
580
  unsigned char temp[MI_SPLIT_LENGTH+MI_DYN_DELETE_BLOCK_HEADER];
595
581
 
596
582
  next_delete_block=HA_OFFSET_ERROR;
689
675
        /* Make a long block for one write */
690
676
  record_end= *record+length-head_length;
691
677
  del_length=(res_length ? MI_DYN_DELETE_BLOCK_HEADER : 0);
692
 
  memcpy(*record - head_length, temp, head_length);
 
678
  memmove(*record - head_length, temp, head_length);
693
679
  memcpy(temp,record_end,(size_t) (extra_length+del_length));
694
680
  memset(record_end, 0, extra_length);
695
681
 
697
683
  {
698
684
    /* Check first if we can join this block with the next one */
699
685
    MI_BLOCK_INFO del_block;
700
 
    my_off_t next_block=filepos+length+extra_length+res_length;
 
686
    internal::my_off_t next_block=filepos+length+extra_length+res_length;
701
687
 
702
688
    del_block.second_read=0;
703
689
    if (next_block < info->state->data_file_length &&
731
717
    if (info->update & HA_STATE_EXTEND_BLOCK)
732
718
    {
733
719
      info->update&= ~HA_STATE_EXTEND_BLOCK;
734
 
      if (my_block_write(&info->rec_cache,(unsigned char*) *record-head_length,
 
720
      if (info->rec_cache.block_write(*record - head_length,
735
721
                         length+extra_length+del_length,filepos))
736
722
      goto err;
737
723
    }
738
 
    else if (my_b_write(&info->rec_cache,(unsigned char*) *record-head_length,
739
 
                        length+extra_length+del_length))
 
724
    else if (info->rec_cache.write(*record-head_length, length+extra_length+del_length))
740
725
      goto err;
741
726
  }
742
727
  else
767
752
 
768
753
        /* update record from datafile */
769
754
 
770
 
static int update_dynamic_record(MI_INFO *info, my_off_t filepos, unsigned char *record,
 
755
static int update_dynamic_record(MI_INFO *info, internal::my_off_t filepos, unsigned char *record,
771
756
                                 ulong reclength)
772
757
{
773
758
  int flag;
800
785
        & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | BLOCK_FATAL_ERROR))
801
786
    {
802
787
      if (!(error & BLOCK_FATAL_ERROR))
803
 
        my_errno=HA_ERR_WRONG_IN_RECORD;
 
788
        errno=HA_ERR_WRONG_IN_RECORD;
804
789
      goto err;
805
790
    }
806
791
 
813
798
          info->state->empty - info->state->del * MI_MAX_DYN_BLOCK_HEADER <
814
799
          reclength - block_info.rec_len + MI_MAX_DYN_BLOCK_HEADER)
815
800
      {
816
 
        my_errno=HA_ERR_RECORD_FILE_FULL;
 
801
        errno=HA_ERR_RECORD_FILE_FULL;
817
802
        goto err;
818
803
      }
819
804
    }
830
815
             BLOCK_FATAL_ERROR))
831
816
      {
832
817
        if (!(error & BLOCK_FATAL_ERROR))
833
 
          my_errno=HA_ERR_WRONG_IN_RECORD;
 
818
          errno=HA_ERR_WRONG_IN_RECORD;
834
819
        goto err;
835
820
      }
836
821
      length=(ulong) (block_info.filepos-filepos) + block_info.block_len;
839
824
        uint32_t tmp=MY_ALIGN(reclength - length + 3 +
840
825
                          test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
841
826
        /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
842
 
        tmp= cmin(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
 
827
        tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
843
828
        /* Check if we can extend this block */
844
829
        if (block_info.filepos + block_info.block_len ==
845
830
            info->state->data_file_length &&
877
862
                New block was too big, link overflow part back to
878
863
                delete list
879
864
              */
880
 
              my_off_t next_pos;
 
865
              internal::my_off_t next_pos;
881
866
              ulong rest_length= length-MI_MAX_BLOCK_LENGTH;
882
 
              set_if_bigger(rest_length, MI_MIN_BLOCK_LENGTH);
 
867
              set_if_bigger(rest_length, (ulong)MI_MIN_BLOCK_LENGTH);
883
868
              next_pos= del_block.filepos+ del_block.block_len - rest_length;
884
869
 
885
870
              if (update_backward_delete_link(info, info->s->state.dellink,
1011
996
      }
1012
997
      else if (type == FIELD_VARCHAR)
1013
998
      {
1014
 
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
 
999
        uint32_t pack_length= ha_varchar_packlength(rec->length -1);
1015
1000
        uint32_t tmp_length;
1016
1001
        if (pack_length == 1)
1017
1002
        {
1117
1102
            goto err;
1118
1103
          if (rec->length > 255 && new_length > 127)
1119
1104
          {
1120
 
            /* purecov: begin inspected */
1121
1105
            if (to[0] != (unsigned char) ((new_length & 127) + 128) ||
1122
1106
                to[1] != (unsigned char) (new_length >> 7))
1123
1107
              goto err;
1124
1108
            to+=2;
1125
 
            /* purecov: end */
1126
1109
          }
1127
1110
          else if (*to++ != (unsigned char) new_length)
1128
1111
            goto err;
1133
1116
      }
1134
1117
      else if (type == FIELD_VARCHAR)
1135
1118
      {
1136
 
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
 
1119
        uint32_t pack_length= ha_varchar_packlength(rec->length -1);
1137
1120
        uint32_t tmp_length;
1138
1121
        if (pack_length == 1)
1139
1122
        {
1178
1161
 
1179
1162
 
1180
1163
        /* Unpacks a record */
1181
 
        /* Returns -1 and my_errno =HA_ERR_RECORD_DELETED if reclength isn't */
 
1164
        /* Returns -1 and errno =HA_ERR_RECORD_DELETED if reclength isn't */
1182
1165
        /* right. Returns reclength (>0) if ok */
1183
1166
 
1184
1167
ulong _mi_rec_unpack(register MI_INFO *info, register unsigned char *to, unsigned char *from,
1206
1189
    {
1207
1190
      if (type == FIELD_VARCHAR)
1208
1191
      {
1209
 
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec_length-1);
 
1192
        uint32_t pack_length= ha_varchar_packlength(rec_length-1);
1210
1193
        if (pack_length == 1)
1211
1194
        {
1212
1195
          length= (uint) *(unsigned char*) from;
1307
1290
    return(found_length);
1308
1291
 
1309
1292
err:
1310
 
  my_errno= HA_ERR_WRONG_IN_RECORD;
 
1293
  errno= HA_ERR_WRONG_IN_RECORD;
1311
1294
  return(MY_FILE_ERROR);
1312
1295
} /* _mi_rec_unpack */
1313
1296
 
1401
1384
    -1          Error
1402
1385
*/
1403
1386
 
1404
 
int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
 
1387
int _mi_read_dynamic_record(MI_INFO *info, internal::my_off_t filepos, unsigned char *buf)
1405
1388
{
1406
1389
  int block_of_record;
1407
1390
  uint32_t b_type, left_length= 0;
1408
1391
  unsigned char *to= NULL;
1409
1392
  MI_BLOCK_INFO block_info;
1410
 
  File file;
 
1393
  int file;
1411
1394
 
1412
1395
  if (filepos != HA_OFFSET_ERROR)
1413
1396
  {
1421
1404
        goto panic;
1422
1405
      if (info->opt_flag & WRITE_CACHE_USED &&
1423
1406
          info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
1424
 
          flush_io_cache(&info->rec_cache))
 
1407
          info->rec_cache.flush())
1425
1408
        goto err;
1426
1409
      info->rec_cache.seek_not_done=1;
1427
1410
      if ((b_type= _mi_get_block_info(&block_info, file, filepos))
1429
1412
             BLOCK_FATAL_ERROR))
1430
1413
      {
1431
1414
        if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED))
1432
 
          my_errno=HA_ERR_RECORD_DELETED;
 
1415
          errno=HA_ERR_RECORD_DELETED;
1433
1416
        goto err;
1434
1417
      }
1435
1418
      if (block_of_record++ == 0)                       /* First block */
1469
1452
      {
1470
1453
        if (info->opt_flag & WRITE_CACHE_USED &&
1471
1454
            info->rec_cache.pos_in_file < filepos + block_info.data_len &&
1472
 
            flush_io_cache(&info->rec_cache))
 
1455
            info->rec_cache.flush())
1473
1456
          goto err;
1474
1457
        /*
1475
1458
          What a pity that this method is not called 'file_pread' and that
1494
1477
  return(-1);                   /* Wrong data to read */
1495
1478
 
1496
1479
panic:
1497
 
  my_errno=HA_ERR_WRONG_IN_RECORD;
 
1480
  errno=HA_ERR_WRONG_IN_RECORD;
1498
1481
err:
1499
1482
  _mi_writeinfo(info,0);
1500
1483
  return(-1);
1503
1486
        /* compare unique constraint between stored rows */
1504
1487
 
1505
1488
int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
1506
 
                           const unsigned char *record, my_off_t pos)
 
1489
                           const unsigned char *record, internal::my_off_t pos)
1507
1490
{
1508
1491
  unsigned char *rec_buff,*old_record;
1509
1492
  int error;
1510
1493
 
1511
 
  if (!(old_record=my_alloca(info->s->base.reclength)))
 
1494
  if (!(old_record=(unsigned char *)malloc(info->s->base.reclength)))
1512
1495
    return(1);
1513
1496
 
1514
1497
  /* Don't let the compare destroy blobs that may be in use */
1521
1504
  if (info->s->base.blobs)
1522
1505
  {
1523
1506
    void * rec_buff_ptr= mi_get_rec_buff_ptr(info, info->rec_buff);
1524
 
    if (rec_buff_ptr != NULL)
1525
 
      free(rec_buff_ptr);
 
1507
    free(rec_buff_ptr);
1526
1508
    info->rec_buff=rec_buff;
1527
1509
  }
1528
 
  my_afree(old_record);
 
1510
  free(old_record);
1529
1511
  return(error);
1530
1512
}
1531
1513
 
1535
1517
int _mi_cmp_dynamic_record(register MI_INFO *info, register const unsigned char *record)
1536
1518
{
1537
1519
  uint32_t flag,reclength,b_type;
1538
 
  my_off_t filepos;
 
1520
  internal::my_off_t filepos;
1539
1521
  unsigned char *buffer;
1540
1522
  MI_BLOCK_INFO block_info;
1541
1523
 
1542
1524
  if (info->opt_flag & WRITE_CACHE_USED)
1543
1525
  {
1544
1526
    info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
1545
 
    if (flush_io_cache(&info->rec_cache))
 
1527
    if (info->rec_cache.flush())
1546
1528
      return(-1);
1547
1529
  }
1548
1530
  info->rec_cache.seek_not_done=1;
1554
1536
  {                                             /* If check isn't disabled  */
1555
1537
    if (info->s->base.blobs)
1556
1538
    {
1557
 
      if (!(buffer=(unsigned char*) my_alloca(info->s->base.pack_reclength+
 
1539
      if (!(buffer=(unsigned char*) malloc(info->s->base.pack_reclength+
1558
1540
                                     _my_calc_total_blob_length(info,record))))
1559
1541
        return(-1);
1560
1542
    }
1572
1554
             BLOCK_FATAL_ERROR))
1573
1555
      {
1574
1556
        if (b_type & (BLOCK_SYNC_ERROR | BLOCK_DELETED))
1575
 
          my_errno=HA_ERR_RECORD_CHANGED;
 
1557
          errno=HA_ERR_RECORD_CHANGED;
1576
1558
        goto err;
1577
1559
      }
1578
1560
      if (flag == 0)                            /* First block */
1580
1562
        flag=1;
1581
1563
        if (reclength != block_info.rec_len)
1582
1564
        {
1583
 
          my_errno=HA_ERR_RECORD_CHANGED;
 
1565
          errno=HA_ERR_RECORD_CHANGED;
1584
1566
          goto err;
1585
1567
        }
1586
1568
      } else if (reclength < block_info.data_len)
1587
1569
      {
1588
 
        my_errno=HA_ERR_WRONG_IN_RECORD;
 
1570
        errno=HA_ERR_WRONG_IN_RECORD;
1589
1571
        goto err;
1590
1572
      }
1591
1573
      reclength-=block_info.data_len;
1592
1574
      if (_mi_cmp_buffer(info->dfile,record,block_info.filepos,
1593
1575
                         block_info.data_len))
1594
1576
      {
1595
 
        my_errno=HA_ERR_RECORD_CHANGED;
 
1577
        errno=HA_ERR_RECORD_CHANGED;
1596
1578
        goto err;
1597
1579
      }
1598
1580
      flag=1;
1599
1581
      record+=block_info.data_len;
1600
1582
    }
1601
1583
  }
1602
 
  my_errno=0;
 
1584
  errno=0;
1603
1585
err:
1604
1586
  if (buffer != info->rec_buff)
1605
 
    my_afree((unsigned char*) buffer);
1606
 
  return(my_errno);
 
1587
    free((unsigned char*) buffer);
 
1588
  return(errno);
1607
1589
}
1608
1590
 
1609
1591
 
1610
1592
        /* Compare file to buffert */
1611
1593
 
1612
 
static int _mi_cmp_buffer(File file, const unsigned char *buff, my_off_t filepos,
 
1594
static int _mi_cmp_buffer(int file, const unsigned char *buff, internal::my_off_t filepos,
1613
1595
                          uint32_t length)
1614
1596
{
1615
1597
  uint32_t next_length;
1670
1652
*/
1671
1653
 
1672
1654
int _mi_read_rnd_dynamic_record(MI_INFO *info, unsigned char *buf,
1673
 
                                register my_off_t filepos,
 
1655
                                register internal::my_off_t filepos,
1674
1656
                                bool skip_deleted_blocks)
1675
1657
{
1676
1658
  int block_of_record, info_read, save_errno;
1704
1686
      }
1705
1687
      if (filepos >= info->state->data_file_length)
1706
1688
      {
1707
 
        my_errno= HA_ERR_END_OF_FILE;
 
1689
        errno= HA_ERR_END_OF_FILE;
1708
1690
        goto err;
1709
1691
      }
1710
1692
    }
1721
1703
    {
1722
1704
      if (info->opt_flag & WRITE_CACHE_USED &&
1723
1705
          info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
1724
 
          flush_io_cache(&info->rec_cache))
1725
 
        return(my_errno);
 
1706
          info->rec_cache.flush())
 
1707
        return(errno);
1726
1708
      info->rec_cache.seek_not_done=1;
1727
1709
      b_type=_mi_get_block_info(&block_info,info->dfile,filepos);
1728
1710
    }
1739
1721
      }
1740
1722
      if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
1741
1723
      {
1742
 
        my_errno=HA_ERR_RECORD_DELETED;
 
1724
        errno=HA_ERR_RECORD_DELETED;
1743
1725
        info->lastpos=block_info.filepos;
1744
1726
        info->nextpos=block_info.filepos+block_info.block_len;
1745
1727
      }
1796
1778
        if (info->opt_flag & WRITE_CACHE_USED &&
1797
1779
            info->rec_cache.pos_in_file <
1798
1780
            block_info.filepos + block_info.data_len &&
1799
 
            flush_io_cache(&info->rec_cache))
 
1781
            info->rec_cache.flush())
1800
1782
          goto err;
1801
 
        /* my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0)); */
1802
 
        if (my_read(info->dfile,(unsigned char*) to,block_info.data_len,MYF(MY_NABP)))
 
1783
        /* lseek(info->dfile,filepos,SEEK_SET); */
 
1784
        if (internal::my_read(info->dfile,(unsigned char*) to,block_info.data_len,MYF(MY_NABP)))
1803
1785
        {
1804
 
          if (my_errno == -1)
1805
 
            my_errno= HA_ERR_WRONG_IN_RECORD;   /* Unexpected end of file */
 
1786
          if (errno == -1)
 
1787
            errno= HA_ERR_WRONG_IN_RECORD;      /* Unexpected end of file */
1806
1788
          goto err;
1807
1789
        }
1808
1790
      }
1826
1808
  if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
1827
1809
      MY_FILE_ERROR)
1828
1810
    return(0);
1829
 
  return(my_errno);                     /* Wrong record */
 
1811
  return(errno);                        /* Wrong record */
1830
1812
 
1831
1813
panic:
1832
 
  my_errno=HA_ERR_WRONG_IN_RECORD;              /* Something is fatal wrong */
 
1814
  errno=HA_ERR_WRONG_IN_RECORD;         /* Something is fatal wrong */
1833
1815
err:
1834
 
  save_errno=my_errno;
 
1816
  save_errno=errno;
1835
1817
  _mi_writeinfo(info,0);
1836
 
  return(my_errno=save_errno);
 
1818
  return(errno=save_errno);
1837
1819
}
1838
1820
 
1839
1821
 
1840
1822
        /* Read and process header from a dynamic-record-file */
1841
1823
 
1842
 
uint32_t _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
 
1824
uint32_t _mi_get_block_info(MI_BLOCK_INFO *info, int file, internal::my_off_t filepos)
1843
1825
{
1844
1826
  uint32_t return_val=0;
1845
1827
  unsigned char *header=info->header;
1851
1833
      pointer set to the end of the header after this function.
1852
1834
      my_pread() may leave the file pointer untouched.
1853
1835
    */
1854
 
    my_seek(file,filepos,MY_SEEK_SET,MYF(0));
1855
 
    if (my_read(file, header, sizeof(info->header),MYF(0)) !=
 
1836
    lseek(file,filepos,SEEK_SET);
 
1837
    if (internal::my_read(file, header, sizeof(info->header),MYF(0)) !=
1856
1838
        sizeof(info->header))
1857
1839
      goto err;
1858
1840
  }
1967
1949
  }
1968
1950
 
1969
1951
err:
1970
 
  my_errno=HA_ERR_WRONG_IN_RECORD;       /* Garbage */
 
1952
  errno=HA_ERR_WRONG_IN_RECORD;  /* Garbage */
1971
1953
  return BLOCK_ERROR;
1972
1954
}