~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/maria/ma_test2.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
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 */
 
15
 
 
16
/* Test av isam-databas: stor test */
 
17
 
 
18
#ifndef USE_MY_FUNC             /* We want to be able to dbug this !! */
 
19
#define USE_MY_FUNC
 
20
#endif
 
21
#include "maria_def.h"
 
22
#include "trnman.h"
 
23
#include <m_ctype.h>
 
24
#include <my_bit.h>
 
25
#include "ma_checkpoint.h"
 
26
 
 
27
#define STANDARD_LENGTH 37
 
28
#define MARIA_KEYS 6
 
29
#define MAX_PARTS 4
 
30
#if !defined(MSDOS) && !defined(labs)
 
31
#define labs(a) abs(a)
 
32
#endif
 
33
 
 
34
static void get_options(int argc, char *argv[]);
 
35
static uint rnd(uint max_value);
 
36
static void fix_length(uchar *record,uint length);
 
37
static void put_blob_in_record(uchar *blob_pos,char **blob_buffer,
 
38
                               ulong *length);
 
39
static void copy_key(MARIA_HA *info, uint inx, uchar *record, uchar *key);
 
40
 
 
41
static int verbose= 0, testflag= 0, first_key= 0, async_io= 0, pagecacheing= 0;
 
42
static int write_cacheing= 0, do_locking= 0, rec_pointer_size= 0;
 
43
static int silent= 0, opt_quick_mode= 0, transactional= 0, skip_update= 0;
 
44
static int die_in_middle_of_transaction= 0, pack_fields= 1;
 
45
static int pack_seg= HA_SPACE_PACK, pack_type= HA_PACK_KEY, remove_count= -1;
 
46
static int create_flag= 0, srand_arg= 0, checkpoint= 0;
 
47
static my_bool opt_versioning= 0;
 
48
static uint use_blob= 0, update_count= 0;
 
49
static ulong pagecache_size=8192*32;
 
50
static enum data_file_type record_type= DYNAMIC_RECORD;
 
51
 
 
52
static uint keys=MARIA_KEYS,recant=1000;
 
53
static uint16 key1[1001],key3[5000];
 
54
static uchar record[300],record2[300],key[100],key2[100];
 
55
static uchar read_record[300],read_record2[300],read_record3[300];
 
56
static HA_KEYSEG glob_keyseg[MARIA_KEYS][MAX_PARTS];
 
57
 
 
58
                /* Test program */
 
59
 
 
60
int main(int argc, char *argv[])
 
61
{
 
62
  uint i;
 
63
  int j,n1,n2,n3,error,k;
 
64
  uint write_count,update,dupp_keys,opt_delete,start,length,blob_pos,
 
65
       reclength,ant,found_parts;
 
66
  my_off_t lastpos;
 
67
  ha_rows range_records,records;
 
68
  MARIA_HA *file;
 
69
  MARIA_KEYDEF keyinfo[10];
 
70
  MARIA_COLUMNDEF recinfo[10];
 
71
  MARIA_INFO info;
 
72
  const char *filename;
 
73
  char *blob_buffer;
 
74
  MARIA_CREATE_INFO create_info;
 
75
  MY_INIT(argv[0]);
 
76
 
 
77
  filename= "test2";
 
78
  get_options(argc,argv);
 
79
  if (! async_io)
 
80
    my_disable_async_io=1;
 
81
 
 
82
  maria_data_root= (char *)".";
 
83
  /* Maria requires that we always have a page cache */
 
84
  if (maria_init() ||
 
85
      (init_pagecache(maria_pagecache, pagecache_size, 0, 0,
 
86
                      maria_block_size, MY_WME) == 0) ||
 
87
      ma_control_file_open(TRUE, TRUE) ||
 
88
      (init_pagecache(maria_log_pagecache,
 
89
                      TRANSLOG_PAGECACHE_SIZE, 0, 0,
 
90
                      TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
 
91
      translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
 
92
                    0, 0, maria_log_pagecache,
 
93
                    TRANSLOG_DEFAULT_FLAGS, 0) ||
 
94
      (transactional && (trnman_init(0) || ma_checkpoint_init(0))))
 
95
  {
 
96
    fprintf(stderr, "Error in initialization");
 
97
    exit(1);
 
98
  }
 
99
  if (opt_versioning)
 
100
    init_thr_lock();
 
101
 
 
102
  reclength=STANDARD_LENGTH+60+(use_blob ? 8 : 0);
 
103
  blob_pos=STANDARD_LENGTH+60;
 
104
  keyinfo[0].seg= &glob_keyseg[0][0];
 
105
  keyinfo[0].seg[0].start=0;
 
106
  keyinfo[0].seg[0].length=6;
 
107
  keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT;
 
108
  keyinfo[0].seg[0].language= default_charset_info->number;
 
109
  keyinfo[0].seg[0].flag=(uint8) pack_seg;
 
110
  keyinfo[0].seg[0].null_bit=0;
 
111
  keyinfo[0].seg[0].null_pos=0;
 
112
  keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
 
113
  keyinfo[0].keysegs=1;
 
114
  keyinfo[0].flag = pack_type;
 
115
  keyinfo[0].block_length= 0;                   /* Default block length */
 
116
  keyinfo[1].seg= &glob_keyseg[1][0];
 
117
  keyinfo[1].seg[0].start=7;
 
118
  keyinfo[1].seg[0].length=6;
 
119
  keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
 
120
  keyinfo[1].seg[0].flag=0;
 
121
  keyinfo[1].seg[0].null_bit=0;
 
122
  keyinfo[1].seg[0].null_pos=0;
 
123
  keyinfo[1].seg[1].start=0;                    /* two part key */
 
124
  keyinfo[1].seg[1].length=6;
 
125
  keyinfo[1].seg[1].type=HA_KEYTYPE_NUM;
 
126
  keyinfo[1].seg[1].flag=HA_REVERSE_SORT;
 
127
  keyinfo[1].seg[1].null_bit=0;
 
128
  keyinfo[1].seg[1].null_pos=0;
 
129
  keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
 
130
  keyinfo[1].keysegs=2;
 
131
  keyinfo[1].flag =0;
 
132
  keyinfo[1].block_length= MARIA_MIN_KEY_BLOCK_LENGTH;  /* Diff blocklength */
 
133
  keyinfo[2].seg= &glob_keyseg[2][0];
 
134
  keyinfo[2].seg[0].start=12;
 
135
  keyinfo[2].seg[0].length=8;
 
136
  keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
 
137
  keyinfo[2].seg[0].flag=HA_REVERSE_SORT;
 
138
  keyinfo[2].seg[0].null_bit=0;
 
139
  keyinfo[2].seg[0].null_pos=0;
 
140
  keyinfo[2].key_alg=HA_KEY_ALG_BTREE;
 
141
  keyinfo[2].keysegs=1;
 
142
  keyinfo[2].flag =HA_NOSAME;
 
143
  keyinfo[2].block_length= 0;                   /* Default block length */
 
144
  keyinfo[3].seg= &glob_keyseg[3][0];
 
145
  keyinfo[3].seg[0].start=0;
 
146
  keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0);
 
147
  keyinfo[3].seg[0].type=HA_KEYTYPE_TEXT;
 
148
  keyinfo[3].seg[0].language=default_charset_info->number;
 
149
  keyinfo[3].seg[0].flag=(uint8) pack_seg;
 
150
  keyinfo[3].seg[0].null_bit=0;
 
151
  keyinfo[3].seg[0].null_pos=0;
 
152
  keyinfo[3].key_alg=HA_KEY_ALG_BTREE;
 
153
  keyinfo[3].keysegs=1;
 
154
  keyinfo[3].flag = pack_type;
 
155
  keyinfo[3].block_length= 0;                   /* Default block length */
 
156
  keyinfo[4].seg= &glob_keyseg[4][0];
 
157
  keyinfo[4].seg[0].start=0;
 
158
  keyinfo[4].seg[0].length=5;
 
159
  keyinfo[4].seg[0].type=HA_KEYTYPE_TEXT;
 
160
  keyinfo[4].seg[0].language=default_charset_info->number;
 
161
  keyinfo[4].seg[0].flag=0;
 
162
  keyinfo[4].seg[0].null_bit=0;
 
163
  keyinfo[4].seg[0].null_pos=0;
 
164
  keyinfo[4].key_alg=HA_KEY_ALG_BTREE;
 
165
  keyinfo[4].keysegs=1;
 
166
  keyinfo[4].flag = pack_type;
 
167
  keyinfo[4].block_length= 0;                   /* Default block length */
 
168
  keyinfo[5].seg= &glob_keyseg[5][0];
 
169
  keyinfo[5].seg[0].start=0;
 
170
  keyinfo[5].seg[0].length=4;
 
171
  keyinfo[5].seg[0].type=HA_KEYTYPE_TEXT;
 
172
  keyinfo[5].seg[0].language=default_charset_info->number;
 
173
  keyinfo[5].seg[0].flag=pack_seg;
 
174
  keyinfo[5].seg[0].null_bit=0;
 
175
  keyinfo[5].seg[0].null_pos=0;
 
176
  keyinfo[5].key_alg=HA_KEY_ALG_BTREE;
 
177
  keyinfo[5].keysegs=1;
 
178
  keyinfo[5].flag = pack_type;
 
179
  keyinfo[5].block_length= 0;                   /* Default block length */
 
180
 
 
181
  recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
 
182
  recinfo[0].length=7;
 
183
  recinfo[0].null_bit=0;
 
184
  recinfo[0].null_pos=0;
 
185
  recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
 
186
  recinfo[1].length=5;
 
187
  recinfo[1].null_bit=0;
 
188
  recinfo[1].null_pos=0;
 
189
  recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
 
190
  recinfo[2].length=9;
 
191
  recinfo[2].null_bit=0;
 
192
  recinfo[2].null_pos=0;
 
193
  recinfo[3].type=FIELD_NORMAL;
 
194
  recinfo[3].length=STANDARD_LENGTH-7-5-9-4;
 
195
  recinfo[3].null_bit=0;
 
196
  recinfo[3].null_pos=0;
 
197
  recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0;
 
198
  recinfo[4].length=4;
 
199
  recinfo[4].null_bit=0;
 
200
  recinfo[4].null_pos=0;
 
201
  recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0;
 
202
  recinfo[5].length=60;
 
203
  recinfo[5].null_bit=0;
 
204
  recinfo[5].null_pos=0;
 
205
  if (use_blob)
 
206
  {
 
207
    recinfo[6].type=FIELD_BLOB;
 
208
    recinfo[6].length=4+portable_sizeof_char_ptr;
 
209
    recinfo[6].null_bit=0;
 
210
    recinfo[6].null_pos=0;
 
211
  }
 
212
 
 
213
  write_count=update=dupp_keys=opt_delete=0;
 
214
  blob_buffer=0;
 
215
 
 
216
  for (i=1000 ; i>0 ; i--) key1[i]=0;
 
217
  for (i=4999 ; i>0 ; i--) key3[i]=0;
 
218
 
 
219
  if (!silent)
 
220
    printf("- Creating maria-file\n");
 
221
  file= 0;
 
222
  bzero((char*) &create_info,sizeof(create_info));
 
223
  create_info.max_rows=(ha_rows) (rec_pointer_size ?
 
224
                                  (1L << (rec_pointer_size*8))/
 
225
                                  reclength : 0);
 
226
  create_info.reloc_rows=(ha_rows) 100;
 
227
  create_info.transactional= transactional;
 
228
  if (maria_create(filename, record_type, keys,&keyinfo[first_key],
 
229
                use_blob ? 7 : 6, &recinfo[0],
 
230
                0,(MARIA_UNIQUEDEF*) 0,
 
231
                &create_info,create_flag))
 
232
    goto err;
 
233
  if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED)))
 
234
    goto err;
 
235
  maria_begin(file);
 
236
  if (opt_versioning)
 
237
    maria_versioning(file, 1);
 
238
  if (testflag == 1)
 
239
    goto end;
 
240
  if (checkpoint == 1 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
241
    goto err;
 
242
  if (!silent)
 
243
    printf("- Writing key:s\n");
 
244
  if (do_locking)
 
245
    maria_lock_database(file,F_WRLCK);
 
246
  if (write_cacheing)
 
247
    maria_extra(file,HA_EXTRA_WRITE_CACHE,0);
 
248
  if (opt_quick_mode)
 
249
    maria_extra(file,HA_EXTRA_QUICK,0);
 
250
 
 
251
  for (i=0 ; i < recant ; i++)
 
252
  {
 
253
    ulong blob_length;
 
254
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
 
255
    sprintf((char*) record,"%6d:%4d:%8d:Pos: %4d    ",n1,n2,n3,write_count);
 
256
    int4store(record+STANDARD_LENGTH-4,(long) i);
 
257
    fix_length(record,(uint) STANDARD_LENGTH+rnd(60));
 
258
    put_blob_in_record(record+blob_pos,&blob_buffer, &blob_length);
 
259
    DBUG_PRINT("test",("record: %d  blob_length: %lu", i, blob_length));
 
260
 
 
261
    if (maria_write(file,record))
 
262
    {
 
263
      if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
 
264
      {
 
265
        printf("Error: %d in write at record: %d\n",my_errno,i);
 
266
        goto err;
 
267
      }
 
268
      if (verbose) printf("   Double key: %d at record# %d\n", n3, i);
 
269
    }
 
270
    else
 
271
    {
 
272
      if (key3[n3] == 1 && first_key <3 && first_key+keys >= 3)
 
273
      {
 
274
        printf("Error: Didn't get error when writing second key: '%8d'\n",n3);
 
275
        goto err;
 
276
      }
 
277
      write_count++; key1[n1]++; key3[n3]=1;
 
278
    }
 
279
 
 
280
    /* Check if we can find key without flushing database */
 
281
    if (i % 10 == 0)
 
282
    {
 
283
      for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
 
284
      if (!j)
 
285
        for (j=999 ; j>0 && key1[j] == 0 ; j--) ;
 
286
      sprintf((char*) key,"%6d",j);
 
287
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
288
      {
 
289
        printf("Test in loop: Can't find key: \"%s\"\n",key);
 
290
        goto err;
 
291
      }
 
292
    }
 
293
  }
 
294
  if (checkpoint == 2 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
295
    goto err;
 
296
 
 
297
  if (write_cacheing)
 
298
  {
 
299
    if (maria_extra(file,HA_EXTRA_NO_CACHE,0))
 
300
    {
 
301
      puts("got error from maria_extra(HA_EXTRA_NO_CACHE)");
 
302
      goto err;
 
303
    }
 
304
  }
 
305
 
 
306
  if (testflag == 2)
 
307
    goto end;
 
308
 
 
309
#ifdef REMOVE_WHEN_WE_HAVE_RESIZE
 
310
  if (pagecacheing)
 
311
    resize_pagecache(maria_pagecache, maria_block_size,
 
312
                     pagecache_size * 2, 0, 0);
 
313
#endif
 
314
  if (!silent)
 
315
    printf("- Delete\n");
 
316
  if (srand_arg)
 
317
    srand(srand_arg);
 
318
  if (!update_count)
 
319
    update_count= recant/10;
 
320
 
 
321
  for (i=0 ; i < update_count ; i++)
 
322
  {
 
323
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
 
324
    if (j != 0)
 
325
    {
 
326
      sprintf((char*) key,"%6d",j);
 
327
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
328
      {
 
329
        printf("can't find key1: \"%s\"\n",key);
 
330
        goto err;
 
331
      }
 
332
      if (bcmp(read_record+keyinfo[0].seg[0].start,
 
333
               key, keyinfo[0].seg[0].length))
 
334
      {
 
335
        printf("Found wrong record when searching for key: \"%s\"\n",key);
 
336
        goto err;
 
337
      }
 
338
      if (opt_delete == (uint) remove_count)            /* While testing */
 
339
        goto end;
 
340
      if (maria_delete(file,read_record))
 
341
      {
 
342
        printf("error: %d; can't delete record: \"%s\"\n", my_errno,read_record);
 
343
        goto err;
 
344
      }
 
345
      opt_delete++;
 
346
      key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
 
347
      key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
 
348
    }
 
349
    else
 
350
      puts("Warning: Skipping delete test because no dupplicate keys");
 
351
  }
 
352
  if (testflag == 3)
 
353
    goto end;
 
354
  if (checkpoint == 3 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
355
    goto err;
 
356
 
 
357
  if (!silent)
 
358
    printf("- Update\n");
 
359
  if (srand_arg)
 
360
    srand(srand_arg);
 
361
  if (!update_count)
 
362
    update_count= recant/10;
 
363
 
 
364
  for (i=0 ; i < update_count ; i++)
 
365
  {
 
366
    n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
 
367
    sprintf((char*) record2,"%6d:%4d:%8d:XXX: %4d     ",n1,n2,n3,update);
 
368
    int4store(record2+STANDARD_LENGTH-4,(long) i);
 
369
    fix_length(record2,(uint) STANDARD_LENGTH+rnd(60));
 
370
 
 
371
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
 
372
    if (j != 0)
 
373
    {
 
374
      sprintf((char*) key,"%6d",j);
 
375
      if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
376
      {
 
377
        printf("can't find key1: \"%s\"\n", (char*) key);
 
378
        goto err;
 
379
      }
 
380
      if (bcmp(read_record+keyinfo[0].seg[0].start,
 
381
               key, keyinfo[0].seg[0].length))
 
382
      {
 
383
        printf("Found wrong record when searching for key: \"%s\"; Found \"%.*s\"\n",
 
384
               key, keyinfo[0].seg[0].length,
 
385
               read_record+keyinfo[0].seg[0].start);
 
386
        goto err;
 
387
      }
 
388
      if (use_blob)
 
389
      {
 
390
        ulong blob_length;
 
391
        if (i & 1)
 
392
          put_blob_in_record(record2+blob_pos,&blob_buffer, &blob_length);
 
393
        else
 
394
          bmove(record2+blob_pos, read_record+blob_pos, 4 + sizeof(char*));
 
395
      }
 
396
      if (skip_update)
 
397
        continue;
 
398
      if (maria_update(file,read_record,record2))
 
399
      {
 
400
        if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
 
401
        {
 
402
          printf("error: %d; can't update:\nFrom: \"%s\"\nTo:   \"%s\"\n",
 
403
                 my_errno,read_record,record2);
 
404
          goto err;
 
405
        }
 
406
        if (verbose)
 
407
          printf("Double key when tried to update:\nFrom: \"%s\"\nTo:   \"%s\"\n",record,record2);
 
408
      }
 
409
      else
 
410
      {
 
411
        key1[atoi((char*) read_record+keyinfo[0].seg[0].start)]--;
 
412
        key3[atoi((char*) read_record+keyinfo[2].seg[0].start)]=0;
 
413
        key1[n1]++; key3[n3]=1;
 
414
        update++;
 
415
      }
 
416
    }
 
417
  }
 
418
  if (testflag == 4)
 
419
    goto end;
 
420
  if (checkpoint == 4 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
421
    goto err;
 
422
 
 
423
  for (i=999, dupp_keys=j=0 ; i>0 ; i--)
 
424
  {
 
425
    if (key1[i] > dupp_keys)
 
426
    {
 
427
      dupp_keys=key1[i]; j=i;
 
428
    }
 
429
  }
 
430
  sprintf((char*) key,"%6d",j);
 
431
  start=keyinfo[0].seg[0].start;
 
432
  length=keyinfo[0].seg[0].length;
 
433
  if (dupp_keys)
 
434
  {
 
435
    if (!silent)
 
436
      printf("- Same key: first - next -> last - prev -> first\n");
 
437
    DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
 
438
    if (verbose) printf("        Using key: \"%s\"  Keys: %d\n",key,dupp_keys);
 
439
 
 
440
    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
441
      goto err;
 
442
    if (maria_rsame(file,read_record2,-1))
 
443
      goto err;
 
444
    if (memcmp(read_record,read_record2,reclength) != 0)
 
445
    {
 
446
      printf("maria_rsame didn't find same record\n");
 
447
      goto err;
 
448
    }
 
449
    info.recpos=maria_position(file);
 
450
    if (maria_rfirst(file,read_record2,0) ||
 
451
        maria_rsame_with_pos(file,read_record2,0,info.recpos) ||
 
452
        memcmp(read_record,read_record2,reclength) != 0)
 
453
    {
 
454
      printf("maria_rsame_with_pos didn't find same record\n");
 
455
      goto err;
 
456
    }
 
457
    {
 
458
      int skr;
 
459
      info.recpos= maria_position(file);
 
460
      skr= maria_rnext(file,read_record2,0);
 
461
      if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
 
462
          maria_rprev(file,read_record2,0) ||
 
463
          memcmp(read_record,read_record2,reclength) != 0 ||
 
464
          info.recpos != maria_position(file))
 
465
      {
 
466
        printf("maria_rsame_with_pos lost position\n");
 
467
        goto err;
 
468
      }
 
469
    }
 
470
    ant=1;
 
471
    while (maria_rnext(file,read_record2,0) == 0 &&
 
472
           memcmp(read_record2+start,key,length) == 0) ant++;
 
473
    if (ant != dupp_keys)
 
474
    {
 
475
      printf("next: Found: %d keys of %d\n",ant,dupp_keys);
 
476
      goto err;
 
477
    }
 
478
    ant=0;
 
479
    while (maria_rprev(file,read_record3,0) == 0 &&
 
480
           bcmp(read_record3+start,key,length) == 0) ant++;
 
481
    if (ant != dupp_keys)
 
482
    {
 
483
      printf("prev: Found: %d records of %d\n",ant,dupp_keys);
 
484
      goto err;
 
485
    }
 
486
 
 
487
    /* Check of maria_rnext_same */
 
488
    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
489
      goto err;
 
490
    ant=1;
 
491
    while (!maria_rnext_same(file,read_record3) && ant < dupp_keys+10)
 
492
      ant++;
 
493
    if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
 
494
    {
 
495
      printf("maria_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
 
496
      goto err;
 
497
    }
 
498
  }
 
499
 
 
500
  if (!silent)
 
501
    printf("- All keys: first - next -> last - prev -> first\n");
 
502
  DBUG_PRINT("progpos",("All keys: first - next -> last - prev -> first"));
 
503
  ant=1;
 
504
  if (maria_rfirst(file,read_record,0))
 
505
  {
 
506
    printf("Can't find first record\n");
 
507
    goto err;
 
508
  }
 
509
  while ((error=maria_rnext(file,read_record3,0)) == 0 && ant < write_count+10)
 
510
    ant++;
 
511
  if (ant != write_count - opt_delete || error != HA_ERR_END_OF_FILE)
 
512
  {
 
513
    printf("next: I found: %d records of %d (error: %d)\n",
 
514
           ant, write_count - opt_delete, error);
 
515
    goto err;
 
516
  }
 
517
  if (maria_rlast(file,read_record2,0) ||
 
518
      bcmp(read_record2,read_record3,reclength))
 
519
  {
 
520
    printf("Can't find last record\n");
 
521
    DBUG_DUMP("record2",(uchar*) read_record2,reclength);
 
522
    DBUG_DUMP("record3",(uchar*) read_record3,reclength);
 
523
    goto err;
 
524
  }
 
525
  ant=1;
 
526
  while (maria_rprev(file,read_record3,0) == 0 && ant < write_count+10)
 
527
    ant++;
 
528
  if (ant != write_count - opt_delete)
 
529
  {
 
530
    printf("prev: I found: %d records of %d\n",ant,write_count);
 
531
    goto err;
 
532
  }
 
533
  if (bcmp(read_record,read_record3,reclength))
 
534
  {
 
535
    printf("Can't find first record\n");
 
536
    goto err;
 
537
  }
 
538
 
 
539
  if (!silent)
 
540
    printf("- Test if: Read first - next - prev - prev - next == first\n");
 
541
  DBUG_PRINT("progpos",("- Read first - next - prev - prev - next == first"));
 
542
  if (maria_rfirst(file,read_record,0) ||
 
543
      maria_rnext(file,read_record3,0) ||
 
544
      maria_rprev(file,read_record3,0) ||
 
545
      maria_rprev(file,read_record3,0) == 0 ||
 
546
      maria_rnext(file,read_record3,0))
 
547
      goto err;
 
548
  if (bcmp(read_record,read_record3,reclength) != 0)
 
549
     printf("Can't find first record\n");
 
550
 
 
551
  if (!silent)
 
552
    printf("- Test if: Read last - prev - next - next - prev == last\n");
 
553
  DBUG_PRINT("progpos",("Read last - prev - next - next - prev == last"));
 
554
  if (maria_rlast(file,read_record2,0) ||
 
555
      maria_rprev(file,read_record3,0) ||
 
556
      maria_rnext(file,read_record3,0) ||
 
557
      maria_rnext(file,read_record3,0) == 0 ||
 
558
      maria_rprev(file,read_record3,0))
 
559
      goto err;
 
560
  if (bcmp(read_record2,read_record3,reclength))
 
561
     printf("Can't find last record\n");
 
562
#ifdef NOT_ANYMORE
 
563
  if (!silent)
 
564
    puts("- Test read key-part");
 
565
  strmov(key2,key);
 
566
  for(i=strlen(key2) ; i-- > 1 ;)
 
567
  {
 
568
    key2[i]=0;
 
569
 
 
570
    /* The following row is just to catch some bugs in the key code */
 
571
    bzero((char*) file->lastkey,file->s->base.max_key_length*2);
 
572
    if (maria_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX))
 
573
      goto err;
 
574
    if (bcmp(read_record+start,key,(uint) i))
 
575
    {
 
576
      puts("Didn't find right record");
 
577
      goto err;
 
578
    }
 
579
  }
 
580
#endif
 
581
  if (dupp_keys > 2)
 
582
  {
 
583
    if (!silent)
 
584
      printf("- Read key (first) - next - delete - next -> last\n");
 
585
    DBUG_PRINT("progpos",("first - next - delete - next -> last"));
 
586
    if (maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
587
      goto err;
 
588
    if (maria_rnext(file,read_record3,0)) goto err;
 
589
    if (maria_delete(file,read_record3)) goto err;
 
590
    opt_delete++;
 
591
    ant=1;
 
592
    while (maria_rnext(file,read_record3,0) == 0 &&
 
593
           bcmp(read_record3+start,key,length) == 0) ant++;
 
594
    if (ant != dupp_keys-1)
 
595
    {
 
596
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1);
 
597
      goto err;
 
598
    }
 
599
  }
 
600
  if (dupp_keys>4)
 
601
  {
 
602
    if (!silent)
 
603
      printf("- Read last of key - prev - delete - prev -> first\n");
 
604
    DBUG_PRINT("progpos",("last - prev - delete - prev -> first"));
 
605
    if (maria_rprev(file,read_record3,0)) goto err;
 
606
    if (maria_rprev(file,read_record3,0)) goto err;
 
607
    if (maria_delete(file,read_record3)) goto err;
 
608
    opt_delete++;
 
609
    ant=1;
 
610
    while (maria_rprev(file,read_record3,0) == 0 &&
 
611
           bcmp(read_record3+start,key,length) == 0) ant++;
 
612
    if (ant != dupp_keys-2)
 
613
    {
 
614
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2);
 
615
      goto err;
 
616
    }
 
617
  }
 
618
  if (dupp_keys > 6)
 
619
  {
 
620
    if (!silent)
 
621
      printf("- Read first - delete - next -> last\n");
 
622
    DBUG_PRINT("progpos",("first - delete - next -> last"));
 
623
    if (maria_rkey(file,read_record3,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT))
 
624
      goto err;
 
625
    if (maria_delete(file,read_record3)) goto err;
 
626
    opt_delete++;
 
627
    ant=1;
 
628
    if (maria_rnext(file,read_record,0))
 
629
      goto err;                                 /* Skall finnas poster */
 
630
    while (maria_rnext(file,read_record3,0) == 0 &&
 
631
           bcmp(read_record3+start,key,length) == 0) ant++;
 
632
    if (ant != dupp_keys-3)
 
633
    {
 
634
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3);
 
635
      goto err;
 
636
    }
 
637
 
 
638
    if (!silent)
 
639
      printf("- Read last - delete - prev -> first\n");
 
640
    DBUG_PRINT("progpos",("last - delete - prev -> first"));
 
641
    if (maria_rprev(file,read_record3,0)) goto err;
 
642
    if (maria_delete(file,read_record3)) goto err;
 
643
    opt_delete++;
 
644
    ant=0;
 
645
    while (maria_rprev(file,read_record3,0) == 0 &&
 
646
           bcmp(read_record3+start,key,length) == 0) ant++;
 
647
    if (ant != dupp_keys-4)
 
648
    {
 
649
      printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4);
 
650
      goto err;
 
651
    }
 
652
  }
 
653
 
 
654
  if (!silent)
 
655
    puts("- Test if: Read rrnd - same");
 
656
  DBUG_PRINT("progpos",("Read rrnd - same"));
 
657
  assert(maria_scan_init(file) == 0);
 
658
  for (i=0 ; i < write_count ; i++)
 
659
  {
 
660
    int tmp;
 
661
    if ((tmp= maria_scan(file,read_record)) &&
 
662
        tmp != HA_ERR_END_OF_FILE &&
 
663
        tmp != HA_ERR_RECORD_DELETED)
 
664
    {
 
665
      printf("Got error %d when scanning table\n", tmp);
 
666
      break;
 
667
    }
 
668
    if (!tmp)
 
669
    {
 
670
      /* Remember position to last found row */
 
671
      info.recpos= maria_position(file);
 
672
      bmove(read_record2,read_record,reclength);
 
673
    }
 
674
  }
 
675
  maria_scan_end(file);
 
676
  if (i != write_count && i != write_count - opt_delete)
 
677
  {
 
678
    printf("Found wrong number of rows while scanning table\n");
 
679
    goto err;
 
680
  }
 
681
 
 
682
  if (maria_rsame_with_pos(file,read_record,0,info.recpos))
 
683
    goto err;
 
684
  if (bcmp(read_record,read_record2,reclength) != 0)
 
685
  {
 
686
    printf("maria_rsame_with_pos didn't find same record\n");
 
687
    goto err;
 
688
  }
 
689
 
 
690
  for (i=min(2,keys) ; i-- > 0 ;)
 
691
  {
 
692
    if (maria_rsame(file,read_record2,(int) i)) goto err;
 
693
    if (bcmp(read_record,read_record2,reclength) != 0)
 
694
    {
 
695
      printf("maria_rsame didn't find same record\n");
 
696
      goto err;
 
697
    }
 
698
  }
 
699
  if (!silent)
 
700
    puts("- Test maria_records_in_range");
 
701
  maria_status(file,&info,HA_STATUS_VARIABLE);
 
702
  for (i=0 ; i < info.keys ; i++)
 
703
  {
 
704
    key_range min_key, max_key;
 
705
    if (maria_rfirst(file,read_record,(int) i) ||
 
706
        maria_rlast(file,read_record2,(int) i))
 
707
      goto err;
 
708
    copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key);
 
709
    copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2);
 
710
    min_key.key= key;
 
711
    min_key.keypart_map= HA_WHOLE_KEY;
 
712
    min_key.flag= HA_READ_KEY_EXACT;
 
713
    max_key.key= key2;
 
714
    max_key.keypart_map= HA_WHOLE_KEY;
 
715
    max_key.flag= HA_READ_AFTER_KEY;
 
716
 
 
717
    range_records= maria_records_in_range(file,(int) i, &min_key, &max_key);
 
718
    if (range_records < info.records*8/10 ||
 
719
        range_records > info.records*12/10)
 
720
    {
 
721
      printf("maria_records_range returned %ld; Should be about %ld\n",
 
722
             (long) range_records,(long) info.records);
 
723
      goto err;
 
724
    }
 
725
    if (verbose)
 
726
    {
 
727
      printf("maria_records_range returned %ld;  Exact is %ld  (diff: %4.2g %%)\n",
 
728
             (long) range_records, (long) info.records,
 
729
             labs((long) range_records - (long) info.records)*100.0/
 
730
             info.records);
 
731
    }
 
732
  }
 
733
  for (i=0 ; i < 5 ; i++)
 
734
  {
 
735
    for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
 
736
    for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ;
 
737
    if (j != 0 && k != 0)
 
738
    {
 
739
      key_range min_key, max_key;
 
740
      if (j > k)
 
741
        swap_variables(int, j, k);
 
742
      sprintf((char*) key,"%6d",j);
 
743
      sprintf((char*) key2,"%6d",k);
 
744
 
 
745
      min_key.key= key;
 
746
      min_key.keypart_map= HA_WHOLE_KEY;
 
747
      min_key.flag= HA_READ_AFTER_KEY;
 
748
      max_key.key= key2;
 
749
      max_key.keypart_map= HA_WHOLE_KEY;
 
750
      max_key.flag= HA_READ_BEFORE_KEY;
 
751
      range_records= maria_records_in_range(file, 0, &min_key, &max_key);
 
752
      records=0;
 
753
      for (j++ ; j < k ; j++)
 
754
        records+=key1[j];
 
755
      if ((long) range_records < (long) records*7/10-2 ||
 
756
          (long) range_records > (long) records*14/10+2)
 
757
      {
 
758
        printf("maria_records_range for key: %d returned %lu; Should be about %lu\n",
 
759
               i, (ulong) range_records, (ulong) records);
 
760
        goto err;
 
761
      }
 
762
      if (verbose && records)
 
763
      {
 
764
        printf("maria_records_range returned %lu;  Exact is %lu  (diff: %4.2g %%)\n",
 
765
               (ulong) range_records, (ulong) records,
 
766
               labs((long) range_records-(long) records)*100.0/records);
 
767
 
 
768
      }
 
769
    }
 
770
    }
 
771
 
 
772
  if (!silent)
 
773
    printf("- maria_info\n");
 
774
  maria_status(file,&info,HA_STATUS_VARIABLE | HA_STATUS_CONST);
 
775
  if (info.records != write_count-opt_delete || info.deleted > opt_delete + update
 
776
      || info.keys != keys)
 
777
  {
 
778
    puts("Wrong info from maria_info");
 
779
    printf("Got: records: %lu  delete: %lu  i_keys: %d\n",
 
780
           (ulong) info.records, (ulong) info.deleted, info.keys);
 
781
    goto err;
 
782
  }
 
783
  if (verbose)
 
784
  {
 
785
    char buff[80];
 
786
    get_date(buff,3,info.create_time);
 
787
    printf("info: Created %s\n",buff);
 
788
    get_date(buff,3,info.check_time);
 
789
    printf("info: checked %s\n",buff);
 
790
    get_date(buff,3,info.update_time);
 
791
    printf("info: Modified %s\n",buff);
 
792
  }
 
793
 
 
794
  maria_panic(HA_PANIC_WRITE);
 
795
  maria_panic(HA_PANIC_READ);
 
796
  if (maria_is_changed(file))
 
797
    puts("Warning: maria_is_changed reported that datafile was changed");
 
798
 
 
799
  if (!silent)
 
800
    printf("- maria_extra(CACHE) + maria_rrnd.... + maria_extra(NO_CACHE)\n");
 
801
  if (maria_reset(file) || maria_extra(file,HA_EXTRA_CACHE,0))
 
802
  {
 
803
    if (do_locking || (!use_blob && !pack_fields))
 
804
    {
 
805
      puts("got error from maria_extra(HA_EXTRA_CACHE)");
 
806
      goto err;
 
807
    }
 
808
  }
 
809
  ant=0;
 
810
  assert(maria_scan_init(file) == 0);
 
811
  while ((error= maria_scan(file,record)) != HA_ERR_END_OF_FILE &&
 
812
         ant < write_count + 10)
 
813
    ant+= error ? 0 : 1;
 
814
  maria_scan_end(file);
 
815
  if (ant != write_count-opt_delete)
 
816
  {
 
817
    printf("scan with cache: I can only find: %d records of %d\n",
 
818
           ant,write_count-opt_delete);
 
819
    maria_scan_end(file);
 
820
    goto err;
 
821
  }
 
822
  if (maria_extra(file,HA_EXTRA_NO_CACHE,0))
 
823
  {
 
824
    puts("got error from maria_extra(HA_EXTRA_NO_CACHE)");
 
825
    maria_scan_end(file);
 
826
    goto err;
 
827
  }
 
828
  maria_scan_end(file);
 
829
 
 
830
  ant=0;
 
831
  maria_scan_init(file);
 
832
  while ((error=maria_scan(file,record)) != HA_ERR_END_OF_FILE &&
 
833
         ant < write_count + 10)
 
834
        ant+= error ? 0 : 1;
 
835
  if (ant != write_count-opt_delete)
 
836
  {
 
837
    printf("scan with cache: I can only find: %d records of %d\n",
 
838
           ant,write_count-opt_delete);
 
839
    maria_scan_end(file);
 
840
    goto err;
 
841
  }
 
842
  maria_scan_end(file);
 
843
 
 
844
  if (testflag == 5)
 
845
    goto end;
 
846
  if (checkpoint == 5 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
847
    goto err;
 
848
 
 
849
  if (!silent)
 
850
    printf("- Removing keys\n");
 
851
  DBUG_PRINT("progpos",("Removing keys"));
 
852
  lastpos = HA_OFFSET_ERROR;
 
853
  /* DBUG_POP(); */
 
854
  maria_reset(file);
 
855
  found_parts=0;
 
856
  maria_scan_init(file);
 
857
  while ((error= maria_scan(file,read_record)) != HA_ERR_END_OF_FILE)
 
858
  {
 
859
    info.recpos=maria_position(file);
 
860
    if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR)
 
861
    {
 
862
      printf("maria_rrnd didn't advance filepointer; old: %ld, new: %ld\n",
 
863
             (long) lastpos, (long) info.recpos);
 
864
      goto err;
 
865
    }
 
866
    lastpos=info.recpos;
 
867
    if (error == 0)
 
868
    {
 
869
      if (opt_delete == (uint) remove_count)            /* While testing */
 
870
        goto end;
 
871
      if (rnd(2) == 1 && maria_rsame(file,read_record,-1))
 
872
      {
 
873
        printf("can't find record %lx\n",(long) info.recpos);
 
874
        goto err;
 
875
      }
 
876
      if (use_blob)
 
877
      {
 
878
        ulong blob_length,pos;
 
879
        uchar *ptr;
 
880
        memcpy_fixed(&ptr, read_record+blob_pos+4, sizeof(ptr));
 
881
        blob_length= uint4korr(read_record+blob_pos);
 
882
        for (pos=0 ; pos < blob_length ; pos++)
 
883
        {
 
884
          if (ptr[pos] != (uchar) (blob_length+pos))
 
885
          {
 
886
            printf("Found blob with wrong info at %ld\n",(long) lastpos);
 
887
            maria_scan_end(file);
 
888
            my_errno= 0;
 
889
            goto err;
 
890
          }
 
891
        }
 
892
      }
 
893
      if (maria_delete(file,read_record))
 
894
      {
 
895
        printf("can't delete record: %6.6s, delete_count: %d\n",
 
896
               read_record, opt_delete);
 
897
        maria_scan_end(file);
 
898
        goto err;
 
899
      }
 
900
      opt_delete++;
 
901
    }
 
902
    else
 
903
      found_parts++;
 
904
  }
 
905
  if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED)
 
906
    printf("error: %d from maria_rrnd\n",my_errno);
 
907
  if (write_count != opt_delete)
 
908
  {
 
909
    printf("Deleted only %d of %d records (%d parts)\n",opt_delete,write_count,
 
910
           found_parts);
 
911
    maria_scan_end(file);
 
912
    goto err;
 
913
  }
 
914
  if (testflag == 6)
 
915
    goto end;
 
916
  if (checkpoint == 6 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE))
 
917
    goto err;
 
918
 
 
919
end:
 
920
  maria_scan_end(file);
 
921
  if (die_in_middle_of_transaction)
 
922
  {
 
923
    /* As commit record is not done, UNDO entries needs to be rolled back */
 
924
    switch (die_in_middle_of_transaction) {
 
925
    case 1:
 
926
      /*
 
927
        Flush changed data and index pages go to disk
 
928
        That will also flush log. Recovery will skip REDOs and apply UNDOs.
 
929
      */
 
930
      _ma_flush_table_files(file, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
 
931
                            FLUSH_RELEASE, FLUSH_RELEASE);
 
932
      break;
 
933
    case 2:
 
934
      /*
 
935
        Just flush log. Pages are likely to not be on disk. Recovery will
 
936
        then execute REDOs and UNDOs.
 
937
      */
 
938
      if (translog_flush(file->trn->undo_lsn))
 
939
        goto err;
 
940
      break;
 
941
    case 3:
 
942
      /*
 
943
        Flush nothing. Pages and log are likely to not be on disk. Recovery
 
944
        will then do nothing.
 
945
      */
 
946
      break;
 
947
    case 4:
 
948
      /*
 
949
        Flush changed data pages go to disk. Changed index pages are not
 
950
        flushed. Recovery will skip some REDOs and apply UNDOs.
 
951
      */
 
952
      _ma_flush_table_files(file, MARIA_FLUSH_DATA, FLUSH_RELEASE,
 
953
                            FLUSH_RELEASE);
 
954
      /*
 
955
        We have to flush log separately as the redo for the last key page
 
956
        may not be flushed
 
957
      */
 
958
      if (translog_flush(file->trn->undo_lsn))
 
959
        goto err;
 
960
      break;
 
961
    }
 
962
    printf("Dying on request without maria_commit()/maria_close()\n");
 
963
    exit(0);
 
964
  }
 
965
  if (maria_commit(file))
 
966
    goto err;
 
967
  if (maria_close(file))
 
968
  {
 
969
    file= 0;
 
970
    goto err;
 
971
  }
 
972
  file= 0;
 
973
  maria_panic(HA_PANIC_CLOSE);                  /* Should close log */
 
974
  if (!silent)
 
975
  {
 
976
    printf("\nFollowing test have been made:\n");
 
977
    printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
 
978
    if (rec_pointer_size)
 
979
      printf("Record pointer size:  %d\n",rec_pointer_size);
 
980
    printf("maria_block_size:    %lu\n", maria_block_size);
 
981
    if (write_cacheing)
 
982
      puts("Key cache resized");
 
983
    if (write_cacheing)
 
984
      puts("Write cacheing used");
 
985
    if (write_cacheing)
 
986
      puts("quick mode");
 
987
    if (async_io && do_locking)
 
988
      puts("Asyncron io with locking used");
 
989
    else if (do_locking)
 
990
      puts("Locking used");
 
991
    if (use_blob)
 
992
      puts("blobs used");
 
993
    printf("key cache status: \n\
 
994
blocks used:%10lu\n\
 
995
not flushed:%10lu\n\
 
996
w_requests: %10lu\n\
 
997
writes:     %10lu\n\
 
998
r_requests: %10lu\n\
 
999
reads:      %10lu\n",
 
1000
           maria_pagecache->blocks_used,
 
1001
           maria_pagecache->global_blocks_changed,
 
1002
           (ulong) maria_pagecache->global_cache_w_requests,
 
1003
           (ulong) maria_pagecache->global_cache_write,
 
1004
           (ulong) maria_pagecache->global_cache_r_requests,
 
1005
           (ulong) maria_pagecache->global_cache_read);
 
1006
  }
 
1007
  maria_end();
 
1008
  my_free(blob_buffer, MYF(MY_ALLOW_ZERO_PTR));
 
1009
  my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
 
1010
  return(0);
 
1011
err:
 
1012
  printf("got error: %d when using MARIA-database\n",my_errno);
 
1013
  if (file)
 
1014
  {
 
1015
    if (maria_commit(file))
 
1016
      goto err;
 
1017
    (void)(maria_close(file));
 
1018
  }
 
1019
  maria_end();
 
1020
  return(1);
 
1021
} /* main */
 
1022
 
 
1023
 
 
1024
/* Read options */
 
1025
 
 
1026
static void get_options(int argc, char **argv)
 
1027
{
 
1028
  char *pos,*progname;
 
1029
 
 
1030
  progname= argv[0];
 
1031
 
 
1032
  while (--argc >0 && *(pos = *(++argv)) == '-' ) {
 
1033
    switch(*++pos) {
 
1034
    case 'B':
 
1035
      pack_type= HA_BINARY_PACK_KEY;
 
1036
      break;
 
1037
    case 'b':
 
1038
      use_blob= 1000;
 
1039
      if (*++pos)
 
1040
        use_blob= atol(pos);
 
1041
      break;
 
1042
    case 'K':                           /* Use key cacheing */
 
1043
      pagecacheing=1;
 
1044
      if (*++pos)
 
1045
        pagecache_size=atol(pos);
 
1046
      break;
 
1047
    case 'W':                           /* Use write cacheing */
 
1048
      write_cacheing=1;
 
1049
      if (*++pos)
 
1050
        my_default_record_cache_size=atoi(pos);
 
1051
      break;
 
1052
    case 'd':
 
1053
      remove_count= atoi(++pos);
 
1054
      break;
 
1055
    case 'i':
 
1056
      if (*++pos)
 
1057
        srand(srand_arg= atoi(pos));
 
1058
      break;
 
1059
    case 'L':
 
1060
      do_locking=1;
 
1061
      break;
 
1062
    case 'a':                           /* use asyncron io */
 
1063
      async_io=1;
 
1064
      if (*++pos)
 
1065
        my_default_record_cache_size=atoi(pos);
 
1066
      break;
 
1067
    case 'v':                           /* verbose */
 
1068
      verbose=1;
 
1069
      break;
 
1070
    case 'm':                           /* records */
 
1071
      if ((recant=atoi(++pos)) < 10 && testflag > 2)
 
1072
      {
 
1073
        fprintf(stderr,"record count must be >= 10 (if testflag > 2)\n");
 
1074
        exit(1);
 
1075
      }
 
1076
      break;
 
1077
    case 'e':                           /* maria_block_length */
 
1078
    case 'E':
 
1079
      if ((maria_block_size= atoi(++pos)) < MARIA_MIN_KEY_BLOCK_LENGTH ||
 
1080
          maria_block_size > MARIA_MAX_KEY_BLOCK_LENGTH)
 
1081
      {
 
1082
        fprintf(stderr,"Wrong maria_block_length\n");
 
1083
        exit(1);
 
1084
      }
 
1085
      maria_block_size= my_round_up_to_next_power(maria_block_size);
 
1086
      break;
 
1087
    case 'f':
 
1088
      if ((first_key=atoi(++pos)) < 0 || first_key >= MARIA_KEYS)
 
1089
        first_key=0;
 
1090
      break;
 
1091
    case 'H':
 
1092
      checkpoint= atoi(++pos);
 
1093
      break;
 
1094
    case 'k':
 
1095
      if ((keys=(uint) atoi(++pos)) < 1 ||
 
1096
           keys > (uint) (MARIA_KEYS-first_key))
 
1097
        keys=MARIA_KEYS-first_key;
 
1098
      break;
 
1099
    case 'M':
 
1100
      record_type= BLOCK_RECORD;
 
1101
      break;
 
1102
    case 'P':
 
1103
      pack_type=0;                      /* Don't use DIFF_LENGTH */
 
1104
      pack_seg=0;
 
1105
      break;
 
1106
    case 'R':                           /* Length of record pointer */
 
1107
      rec_pointer_size=atoi(++pos);
 
1108
      if (rec_pointer_size > 7)
 
1109
        rec_pointer_size=0;
 
1110
      break;
 
1111
    case 'S':
 
1112
      pack_fields=0;                    /* Static-length-records */
 
1113
      record_type= STATIC_RECORD;
 
1114
      break;
 
1115
    case 's':
 
1116
      silent=1;
 
1117
      break;
 
1118
    case 't':
 
1119
      testflag=atoi(++pos);             /* testmod */
 
1120
      break;
 
1121
    case 'T':
 
1122
      transactional= 1;
 
1123
      break;
 
1124
    case 'A':
 
1125
      die_in_middle_of_transaction= atoi(++pos);
 
1126
      break;
 
1127
    case 'u':
 
1128
      update_count=atoi(++pos);
 
1129
      if (!update_count)
 
1130
        skip_update= 1;
 
1131
      break;
 
1132
    case 'q':
 
1133
      opt_quick_mode=1;
 
1134
      break;
 
1135
    case 'c':
 
1136
      create_flag|= HA_CREATE_CHECKSUM | HA_CREATE_PAGE_CHECKSUM;
 
1137
      break;
 
1138
    case 'D':
 
1139
      create_flag|=HA_CREATE_DELAY_KEY_WRITE;
 
1140
      break;
 
1141
    case 'g':
 
1142
      skip_update= TRUE;
 
1143
      break;
 
1144
    case 'C':
 
1145
      opt_versioning= 1;
 
1146
      break;
 
1147
    case '?':
 
1148
    case 'I':
 
1149
    case 'V':
 
1150
      printf("%s  Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
 
1151
      puts("By Monty, for testing Maria\n");
 
1152
      printf("Usage: %s [-?AbBcCDIKLPRqSsTVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n",
 
1153
             progname);
 
1154
      exit(0);
 
1155
    case '#':
 
1156
      DBUG_PUSH (++pos);
 
1157
      break;
 
1158
    default:
 
1159
      printf("Illegal option: '%c'\n",*pos);
 
1160
      break;
 
1161
    }
 
1162
  }
 
1163
  return;
 
1164
} /* get options */
 
1165
 
 
1166
        /* Get a random value 0 <= x <= n */
 
1167
 
 
1168
static uint rnd(uint max_value)
 
1169
{
 
1170
  return (uint) ((rand() & 32767)/32767.0*max_value);
 
1171
} /* rnd */
 
1172
 
 
1173
 
 
1174
        /* Create a variable length record */
 
1175
 
 
1176
static void fix_length(uchar *rec, uint length)
 
1177
{
 
1178
  bmove(rec+STANDARD_LENGTH,
 
1179
        "0123456789012345678901234567890123456789012345678901234567890",
 
1180
        length-STANDARD_LENGTH);
 
1181
  strfill((char*) rec+length,STANDARD_LENGTH+60-length,' ');
 
1182
} /* fix_length */
 
1183
 
 
1184
 
 
1185
/* Put maybe a blob in record */
 
1186
 
 
1187
static int first_entry;
 
1188
 
 
1189
static void put_blob_in_record(uchar *blob_pos, char **blob_buffer,
 
1190
                               ulong *blob_length)
 
1191
{
 
1192
  ulong i,length;
 
1193
  *blob_length= 0;
 
1194
  if (use_blob)
 
1195
  {
 
1196
    if (! *blob_buffer &&
 
1197
        !(*blob_buffer=my_malloc((uint) use_blob,MYF(MY_WME))))
 
1198
    {
 
1199
      use_blob= 0;
 
1200
      return;
 
1201
    }
 
1202
    if (rnd(10) == 0)
 
1203
    {
 
1204
      if (first_entry++ == 0)
 
1205
      {
 
1206
        /* Ensure we have at least one blob of max length in file */
 
1207
        length= use_blob;
 
1208
      }
 
1209
      else
 
1210
        length=rnd(use_blob);
 
1211
      for (i=0 ; i < length ; i++)
 
1212
        (*blob_buffer)[i]=(char) (length+i);
 
1213
      int4store(blob_pos,length);
 
1214
      memcpy_fixed(blob_pos+4,(char*) blob_buffer,sizeof(char*));
 
1215
      *blob_length= length;
 
1216
    }
 
1217
    else
 
1218
    {
 
1219
      int4store(blob_pos,0);
 
1220
    }
 
1221
  }
 
1222
  return;
 
1223
}
 
1224
 
 
1225
 
 
1226
static void copy_key(MARIA_HA *info,uint inx,uchar *rec,uchar *key_buff)
 
1227
{
 
1228
  HA_KEYSEG *keyseg;
 
1229
 
 
1230
  for (keyseg=info->s->keyinfo[inx].seg ; keyseg->type ; keyseg++)
 
1231
  {
 
1232
    memcpy(key_buff,rec+keyseg->start,(size_t) keyseg->length);
 
1233
    key_buff+=keyseg->length;
 
1234
  }
 
1235
  return;
 
1236
}
 
1237
 
 
1238
#include "ma_check_standalone.h"