~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_write.c

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* Write a row to a MyISAM table */
17
17
 
18
18
#include "myisamdef.h"
 
19
#include <drizzled/util/test.h>
 
20
 
19
21
 
20
22
#define MAX_POINTER_LENGTH 8
21
23
 
22
24
        /* Functions declared in this file */
23
25
 
24
26
static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,
25
 
                    uint comp_flag, uchar *key,
26
 
                    uint key_length, my_off_t pos, uchar *father_buff,
27
 
                    uchar *father_keypos, my_off_t father_page,
28
 
                    my_bool insert_last);
29
 
static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
30
 
                            uchar *curr_buff,uchar *father_buff,
31
 
                            uchar *father_keypos,my_off_t father_page);
32
 
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
33
 
                                uchar *key, uint *return_key_length,
34
 
                                uchar **after_key);
35
 
int _mi_ck_write_tree(register MI_INFO *info, uint keynr,uchar *key,
36
 
                      uint key_length);
37
 
int _mi_ck_write_btree(register MI_INFO *info, uint keynr,uchar *key,
38
 
                       uint key_length);
 
27
                    uint32_t comp_flag, unsigned char *key,
 
28
                    uint32_t key_length, my_off_t pos, unsigned char *father_buff,
 
29
                    unsigned char *father_keypos, my_off_t father_page,
 
30
                    bool insert_last);
 
31
static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
 
32
                            unsigned char *curr_buff,unsigned char *father_buff,
 
33
                            unsigned char *father_keypos,my_off_t father_page);
 
34
static unsigned char *_mi_find_last_pos(MI_KEYDEF *keyinfo, unsigned char *page,
 
35
                                unsigned char *key, uint32_t *return_key_length,
 
36
                                unsigned char **after_key);
 
37
int _mi_ck_write_tree(register MI_INFO *info, uint32_t keynr,unsigned char *key,
 
38
                      uint32_t key_length);
 
39
int _mi_ck_write_btree(register MI_INFO *info, uint32_t keynr,unsigned char *key,
 
40
                       uint32_t key_length);
39
41
 
40
42
        /* Write new record to database */
41
43
 
42
 
int mi_write(MI_INFO *info, uchar *record)
 
44
int mi_write(MI_INFO *info, unsigned char *record)
43
45
{
44
46
  MYISAM_SHARE *share=info->s;
45
 
  uint i;
 
47
  uint32_t i;
46
48
  int save_errno;
47
49
  my_off_t filepos;
48
 
  uchar *buff;
49
 
  my_bool lock_tree= share->concurrent_insert;
50
 
  DBUG_ENTER("mi_write");
51
 
  DBUG_PRINT("enter",("isam: %d  data: %d",info->s->kfile,info->dfile));
 
50
  unsigned char *buff;
 
51
  bool lock_tree= share->concurrent_insert;
52
52
 
53
 
  DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
54
 
                  mi_print_error(info->s, HA_ERR_CRASHED);
55
 
                  DBUG_RETURN(my_errno= HA_ERR_CRASHED););
56
53
  if (share->options & HA_OPTION_READ_ONLY_DATA)
57
54
  {
58
 
    DBUG_RETURN(my_errno=EACCES);
 
55
    return(my_errno=EACCES);
59
56
  }
60
57
  if (_mi_readinfo(info,F_WRLCK,1))
61
 
    DBUG_RETURN(my_errno);
62
 
#if !defined(NO_LOCKING) && defined(USE_RECORD_LOCK)
63
 
  if (!info->locked && my_lock(info->dfile,F_WRLCK,0L,F_TO_EOF,
64
 
                               MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
65
 
    goto err;
66
 
#endif
 
58
    return(my_errno);
67
59
  filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
68
60
             !info->append_insert_at_end) ?
69
61
            share->state.dellink :
100
92
  {
101
93
    if (mi_is_key_active(share->state.key_map, i))
102
94
    {
103
 
      my_bool local_lock_tree= (lock_tree &&
 
95
      bool local_lock_tree= (lock_tree &&
104
96
                                !(info->bulk_insert &&
105
97
                                  is_tree_inited(&info->bulk_insert[i])));
106
98
      if (local_lock_tree)
114
106
        {
115
107
          if (local_lock_tree)
116
108
            rw_unlock(&share->key_root_lock[i]);
117
 
          DBUG_PRINT("error",("Got error: %d on write",my_errno));
118
109
          goto err;
119
110
        }
120
111
      }
141
132
                 HA_STATE_ROW_CHANGED);
142
133
  info->state->records++;
143
134
  info->lastpos=filepos;
144
 
  myisam_log_record(MI_LOG_WRITE,info,record,filepos,0);
145
 
  VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
 
135
  _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
146
136
  if (info->invalidator != 0)
147
137
  {
148
 
    DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
149
138
    (*info->invalidator)(info->filename);
150
139
    info->invalidator=0;
151
140
  }
161
150
  if (share->is_log_table)
162
151
    mi_update_status((void*) info);
163
152
 
164
 
  DBUG_RETURN(0);
 
153
  return(0);
165
154
 
166
155
err:
167
156
  save_errno=my_errno;
170
159
  {
171
160
    if (info->bulk_insert)
172
161
    {
173
 
      uint j;
 
162
      uint32_t j;
174
163
      for (j=0 ; j < share->base.keys ; j++)
175
164
        mi_flush_bulk_insert(info, j);
176
165
    }
179
168
    {
180
169
      if (mi_is_key_active(share->state.key_map, i))
181
170
      {
182
 
        my_bool local_lock_tree= (lock_tree &&
 
171
        bool local_lock_tree= (lock_tree &&
183
172
                                  !(info->bulk_insert &&
184
173
                                    is_tree_inited(&info->bulk_insert[i])));
185
174
        if (local_lock_tree)
186
175
          rw_wrlock(&share->key_root_lock[i]);
187
176
        {
188
 
          uint key_length=_mi_make_key(info,i,buff,record,filepos);
 
177
          uint32_t key_length=_mi_make_key(info,i,buff,record,filepos);
189
178
          if (_mi_ck_delete(info,i,buff,key_length))
190
179
          {
191
180
            if (local_lock_tree)
207
196
  my_errno=save_errno;
208
197
err2:
209
198
  save_errno=my_errno;
210
 
  myisam_log_record(MI_LOG_WRITE,info,record,filepos,my_errno);
211
 
  VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
212
 
  DBUG_RETURN(my_errno=save_errno);
 
199
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
 
200
  return(my_errno=save_errno);
213
201
} /* mi_write */
214
202
 
215
203
 
216
204
        /* Write one key to btree */
217
205
 
218
 
int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
 
206
int _mi_ck_write(MI_INFO *info, uint32_t keynr, unsigned char *key, uint32_t key_length)
219
207
{
220
 
  DBUG_ENTER("_mi_ck_write");
221
 
 
222
208
  if (info->bulk_insert && is_tree_inited(&info->bulk_insert[keynr]))
223
209
  {
224
 
    DBUG_RETURN(_mi_ck_write_tree(info, keynr, key, key_length));
 
210
    return(_mi_ck_write_tree(info, keynr, key, key_length));
225
211
  }
226
212
  else
227
213
  {
228
 
    DBUG_RETURN(_mi_ck_write_btree(info, keynr, key, key_length));
 
214
    return(_mi_ck_write_btree(info, keynr, key, key_length));
229
215
  }
230
216
} /* _mi_ck_write */
231
217
 
234
220
 *                Normal insert code                                  *
235
221
 **********************************************************************/
236
222
 
237
 
int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
238
 
                       uint key_length)
 
223
int _mi_ck_write_btree(register MI_INFO *info, uint32_t keynr, unsigned char *key,
 
224
                       uint32_t key_length)
239
225
{
240
 
  int error;
241
 
  uint comp_flag;
 
226
  uint32_t error;
 
227
  uint32_t comp_flag;
242
228
  MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
243
229
  my_off_t  *root=&info->s->state.key_root[keynr];
244
 
  DBUG_ENTER("_mi_ck_write_btree");
245
230
 
246
231
  if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
247
232
    comp_flag=SEARCH_BIGGER;                    /* Put after same key */
256
241
 
257
242
  error=_mi_ck_real_write_btree(info, keyinfo, key, key_length,
258
243
                                root, comp_flag);
259
 
  DBUG_RETURN(error);
 
244
  return(error);
260
245
} /* _mi_ck_write_btree */
261
246
 
262
247
int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo,
263
 
    uchar *key, uint key_length, my_off_t *root, uint comp_flag)
 
248
    unsigned char *key, uint32_t key_length, my_off_t *root, uint32_t comp_flag)
264
249
{
265
250
  int error;
266
 
  DBUG_ENTER("_mi_ck_real_write_btree");
267
251
  /* key_length parameter is used only if comp_flag is SEARCH_FIND */
268
252
  if (*root == HA_OFFSET_ERROR ||
269
253
      (error=w_search(info, keyinfo, comp_flag, key, key_length,
270
 
                      *root, (uchar *) 0, (uchar*) 0,
 
254
                      *root, (unsigned char *) 0, (unsigned char*) 0,
271
255
                      (my_off_t) 0, 1)) > 0)
272
256
    error=_mi_enlarge_root(info,keyinfo,key,root);
273
 
  DBUG_RETURN(error);
 
257
  return(error);
274
258
} /* _mi_ck_real_write_btree */
275
259
 
276
260
 
277
261
        /* Make a new root with key as only pointer */
278
262
 
279
 
int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
 
263
int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *key,
280
264
                     my_off_t *root)
281
265
{
282
 
  uint t_length,nod_flag;
 
266
  uint32_t t_length,nod_flag;
283
267
  MI_KEY_PARAM s_temp;
284
268
  MYISAM_SHARE *share=info->s;
285
 
  DBUG_ENTER("_mi_enlarge_root");
286
269
 
287
270
  nod_flag= (*root != HA_OFFSET_ERROR) ?  share->base.key_reflength : 0;
288
271
  _mi_kpointer(info,info->buff+2,*root); /* if nod */
289
 
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0,
290
 
                                (uchar*) 0, (uchar*) 0, key,&s_temp);
 
272
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(unsigned char*) 0,
 
273
                                (unsigned char*) 0, (unsigned char*) 0, key,&s_temp);
291
274
  mi_putint(info->buff,t_length+2+nod_flag,nod_flag);
292
275
  (*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
293
276
  info->buff_used=info->page_changed=1;         /* info->buff is used */
294
277
  if ((*root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
295
278
      _mi_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
296
 
    DBUG_RETURN(-1);
297
 
  DBUG_RETURN(0);
 
279
    return(-1);
 
280
  return(0);
298
281
} /* _mi_enlarge_root */
299
282
 
300
283
 
306
289
        */
307
290
 
308
291
static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
309
 
                    uint comp_flag, uchar *key, uint key_length, my_off_t page,
310
 
                    uchar *father_buff, uchar *father_keypos,
311
 
                    my_off_t father_page, my_bool insert_last)
 
292
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, my_off_t page,
 
293
                    unsigned char *father_buff, unsigned char *father_keypos,
 
294
                    my_off_t father_page, bool insert_last)
312
295
{
313
296
  int error,flag;
314
 
  uint nod_flag, search_key_length;
315
 
  uchar *temp_buff,*keypos;
316
 
  uchar keybuff[MI_MAX_KEY_BUFF];
317
 
  my_bool was_last_key;
 
297
  uint32_t nod_flag, search_key_length;
 
298
  unsigned char *temp_buff,*keypos;
 
299
  unsigned char keybuff[MI_MAX_KEY_BUFF];
 
300
  bool was_last_key;
318
301
  my_off_t next_page, dupp_key_pos;
319
 
  DBUG_ENTER("w_search");
320
 
  DBUG_PRINT("enter",("page: %ld", (long) page));
321
302
 
322
303
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
323
 
  if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
 
304
  if (!(temp_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
324
305
                                      MI_MAX_KEY_BUFF*2)))
325
 
    DBUG_RETURN(-1);
 
306
    return(-1);
326
307
  if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
327
308
    goto err;
328
309
 
331
312
  nod_flag=mi_test_if_nod(temp_buff);
332
313
  if (flag == 0)
333
314
  {
334
 
    uint tmp_key_length;
 
315
    uint32_t tmp_key_length;
335
316
        /* get position to record with duplicated key */
336
317
    tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff);
337
318
    if (tmp_key_length)
341
322
 
342
323
    {
343
324
      info->dupp_key_pos= dupp_key_pos;
344
 
      my_afree((uchar*) temp_buff);
 
325
      my_afree((unsigned char*) temp_buff);
345
326
      my_errno=HA_ERR_FOUND_DUPP_KEY;
346
 
      DBUG_RETURN(-1);
 
327
      return(-1);
347
328
    }
348
329
  }
349
330
  if (flag == MI_FOUND_WRONG_KEY)
350
 
    DBUG_RETURN(-1);
 
331
    return(-1);
351
332
  if (!was_last_key)
352
333
    insert_last=0;
353
334
  next_page=_mi_kpos(nod_flag,keypos);
360
341
    if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff))
361
342
      goto err;
362
343
  }
363
 
  my_afree((uchar*) temp_buff);
364
 
  DBUG_RETURN(error);
 
344
  my_afree((unsigned char*) temp_buff);
 
345
  return(error);
365
346
err:
366
 
  my_afree((uchar*) temp_buff);
367
 
  DBUG_PRINT("exit",("Error: %d",my_errno));
368
 
  DBUG_RETURN (-1);
 
347
  my_afree((unsigned char*) temp_buff);
 
348
  return (-1);
369
349
} /* w_search */
370
350
 
371
351
 
395
375
*/
396
376
 
397
377
int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
398
 
               uchar *key, uchar *anc_buff, uchar *key_pos, uchar *key_buff,
399
 
               uchar *father_buff, uchar *father_key_pos, my_off_t father_page,
400
 
               my_bool insert_last)
 
378
               unsigned char *key, unsigned char *anc_buff, unsigned char *key_pos, unsigned char *key_buff,
 
379
               unsigned char *father_buff, unsigned char *father_key_pos, my_off_t father_page,
 
380
               bool insert_last)
401
381
{
402
 
  uint a_length,nod_flag;
 
382
  uint32_t a_length,nod_flag;
403
383
  int t_length;
404
 
  uchar *endpos, *prev_key;
 
384
  unsigned char *endpos, *prev_key;
405
385
  MI_KEY_PARAM s_temp;
406
 
  DBUG_ENTER("_mi_insert");
407
 
  DBUG_PRINT("enter",("key_pos: 0x%lx", (long) key_pos));
408
 
  DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,USE_WHOLE_KEY););
409
386
 
410
387
  nod_flag=mi_test_if_nod(anc_buff);
411
388
  a_length=mi_getint(anc_buff);
412
389
  endpos= anc_buff+ a_length;
413
 
  prev_key=(key_pos == anc_buff+2+nod_flag ? (uchar*) 0 : key_buff);
 
390
  prev_key=(key_pos == anc_buff+2+nod_flag ? (unsigned char*) 0 : key_buff);
414
391
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
415
 
                                (key_pos == endpos ? (uchar*) 0 : key_pos),
 
392
                                (key_pos == endpos ? (unsigned char*) 0 : key_pos),
416
393
                                prev_key, prev_key,
417
394
                                key,&s_temp);
418
 
#ifndef DBUG_OFF
419
 
  if (key_pos != anc_buff+2+nod_flag && (keyinfo->flag &
420
 
                                         (HA_BINARY_PACK_KEY | HA_PACK_KEY)))
421
 
  {
422
 
    DBUG_DUMP("prev_key",(uchar*) key_buff,_mi_keylength(keyinfo,key_buff));
423
 
  }
424
 
  if (keyinfo->flag & HA_PACK_KEY)
425
 
  {
426
 
    DBUG_PRINT("test",("t_length: %d  ref_len: %d",
427
 
                       t_length,s_temp.ref_length));
428
 
    DBUG_PRINT("test",("n_ref_len: %d  n_length: %d  key_pos: 0x%lx",
429
 
                       s_temp.n_ref_length,s_temp.n_length, (long) s_temp.key));
430
 
  }
431
 
#endif
 
395
 
432
396
  if (t_length > 0)
433
397
  {
434
398
    if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
435
399
    {
436
400
      mi_print_error(info->s, HA_ERR_CRASHED);
437
401
      my_errno=HA_ERR_CRASHED;
438
 
      DBUG_RETURN(-1);
 
402
      return(-1);
439
403
    }
440
 
    bmove_upp((uchar*) endpos+t_length,(uchar*) endpos,(uint) (endpos-key_pos));
 
404
    bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
441
405
  }
442
406
  else
443
407
  {
445
409
    {
446
410
      mi_print_error(info->s, HA_ERR_CRASHED);
447
411
      my_errno=HA_ERR_CRASHED;
448
 
      DBUG_RETURN(-1);
 
412
      return(-1);
449
413
    }
450
 
    bmove(key_pos,key_pos-t_length,(uint) (endpos-key_pos)+t_length);
 
414
    memcpy(key_pos, key_pos - t_length, endpos - key_pos + t_length);
451
415
  }
452
416
  (*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
453
417
  a_length+=t_length;
454
418
  mi_putint(anc_buff,a_length,nod_flag);
455
419
  if (a_length <= keyinfo->block_length)
456
420
  {
457
 
    DBUG_RETURN(0);                             /* There is room on page */
 
421
    return(0);                          /* There is room on page */
458
422
  }
459
423
  /* Page is full */
460
424
  if (nod_flag)
461
425
    insert_last=0;
462
426
  if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
463
427
      father_buff && !insert_last)
464
 
    DBUG_RETURN(_mi_balance_page(info,keyinfo,key,anc_buff,father_buff,
 
428
    return(_mi_balance_page(info,keyinfo,key,anc_buff,father_buff,
465
429
                                 father_key_pos,father_page));
466
 
  DBUG_RETURN(_mi_split_page(info,keyinfo,key,anc_buff,key_buff, insert_last));
 
430
  return(_mi_split_page(info,keyinfo,key,anc_buff,key_buff, insert_last));
467
431
} /* _mi_insert */
468
432
 
469
433
 
470
434
        /* split a full page in two and assign emerging item to key */
471
435
 
472
436
int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
473
 
                   uchar *key, uchar *buff, uchar *key_buff,
474
 
                   my_bool insert_last_key)
 
437
                   unsigned char *key, unsigned char *buff, unsigned char *key_buff,
 
438
                   bool insert_last_key)
475
439
{
476
 
  uint length,a_length,key_ref_length,t_length,nod_flag,key_length;
477
 
  uchar *key_pos,*pos, *after_key= NULL;
 
440
  uint32_t length,a_length,key_ref_length,t_length,nod_flag,key_length;
 
441
  unsigned char *key_pos,*pos, *after_key= NULL;
478
442
  my_off_t new_pos;
479
443
  MI_KEY_PARAM s_temp;
480
 
  DBUG_ENTER("mi_split_page");
481
 
  DBUG_DUMP("buff",(uchar*) buff,mi_getint(buff));
482
444
 
483
445
  if (info->s->keyinfo+info->lastinx == keyinfo)
484
446
    info->page_changed=1;                       /* Info->buff is used */
491
453
    key_pos=_mi_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length,
492
454
                              &after_key);
493
455
  if (!key_pos)
494
 
    DBUG_RETURN(-1);
 
456
    return(-1);
495
457
 
496
458
  length=(uint) (key_pos-buff);
497
459
  a_length=mi_getint(buff);
500
462
  key_pos=after_key;
501
463
  if (nod_flag)
502
464
  {
503
 
    DBUG_PRINT("test",("Splitting nod"));
504
465
    pos=key_pos-nod_flag;
505
 
    memcpy((uchar*) info->buff+2,(uchar*) pos,(size_t) nod_flag);
 
466
    memcpy(info->buff + 2, pos, nod_flag);
506
467
  }
507
468
 
508
469
        /* Move middle item to key and pointer to new page */
509
470
  if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
510
 
    DBUG_RETURN(-1);
 
471
    return(-1);
511
472
  _mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos);
512
473
 
513
474
        /* Store new page */
514
475
  if (!(*keyinfo->get_key)(keyinfo,nod_flag,&key_pos,key_buff))
515
 
    DBUG_RETURN(-1);
 
476
    return(-1);
516
477
 
517
 
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar *) 0,
518
 
                                (uchar*) 0, (uchar*) 0,
 
478
  t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(unsigned char *) 0,
 
479
                                (unsigned char*) 0, (unsigned char*) 0,
519
480
                                key_buff, &s_temp);
520
481
  length=(uint) ((buff+a_length)-key_pos);
521
 
  memcpy((uchar*) info->buff+key_ref_length+t_length,(uchar*) key_pos,
522
 
         (size_t) length);
 
482
  memcpy(info->buff+key_ref_length+t_length, key_pos, length);
523
483
  (*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
524
484
  mi_putint(info->buff,length+t_length+key_ref_length,nod_flag);
525
485
 
526
486
  if (_mi_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
527
 
    DBUG_RETURN(-1);
528
 
  DBUG_DUMP("key",(uchar*) key,_mi_keylength(keyinfo,key));
529
 
  DBUG_RETURN(2);                               /* Middle key up */
 
487
    return(-1);
 
488
  return(2);                            /* Middle key up */
530
489
} /* _mi_split_page */
531
490
 
532
491
 
538
497
          after_key will contain the position to where the next key starts
539
498
        */
540
499
 
541
 
uchar *_mi_find_half_pos(uint nod_flag, MI_KEYDEF *keyinfo, uchar *page,
542
 
                         uchar *key, uint *return_key_length,
543
 
                         uchar **after_key)
 
500
unsigned char *_mi_find_half_pos(uint32_t nod_flag, MI_KEYDEF *keyinfo, unsigned char *page,
 
501
                         unsigned char *key, uint32_t *return_key_length,
 
502
                         unsigned char **after_key)
544
503
{
545
 
  uint keys,length,key_ref_length;
546
 
  uchar *end,*lastpos;
547
 
  DBUG_ENTER("_mi_find_half_pos");
 
504
  uint32_t keys,length,key_ref_length;
 
505
  unsigned char *end,*lastpos;
548
506
 
549
507
  key_ref_length=2+nod_flag;
550
508
  length=mi_getint(page)-key_ref_length;
559
517
    end=page+keys*key_ref_length;
560
518
    *after_key=end+key_ref_length;
561
519
    memcpy(key,end,key_ref_length);
562
 
    DBUG_RETURN(end);
 
520
    return(end);
563
521
  }
564
522
 
565
523
  end=page+length/2-key_ref_length;             /* This is aprox. half */
568
526
  {
569
527
    lastpos=page;
570
528
    if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key)))
571
 
      DBUG_RETURN(0);
 
529
      return(0);
572
530
  } while (page < end);
573
531
  *return_key_length=length;
574
532
  *after_key=page;
575
 
  DBUG_PRINT("exit",("returns: 0x%lx  page: 0x%lx  half: 0x%lx",
576
 
                     (long) lastpos, (long) page, (long) end));
577
 
  DBUG_RETURN(lastpos);
 
533
  return(lastpos);
578
534
} /* _mi_find_half_pos */
579
535
 
580
536
 
584
540
          key will contain the last key
585
541
        */
586
542
 
587
 
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
588
 
                                uchar *key, uint *return_key_length,
589
 
                                uchar **after_key)
 
543
static unsigned char *_mi_find_last_pos(MI_KEYDEF *keyinfo, unsigned char *page,
 
544
                                unsigned char *key, uint32_t *return_key_length,
 
545
                                unsigned char **after_key)
590
546
{
591
 
  uint keys, length, last_length, key_ref_length;
592
 
  uchar *end, *lastpos, *prevpos= NULL;
593
 
  uchar key_buff[MI_MAX_KEY_BUFF];
594
 
  DBUG_ENTER("_mi_find_last_pos");
 
547
  uint32_t keys;
 
548
  uint32_t length;
 
549
  uint32_t last_length= 0;
 
550
  uint32_t key_ref_length;
 
551
  unsigned char *end, *lastpos, *prevpos= NULL;
 
552
  unsigned char key_buff[MI_MAX_KEY_BUFF];
595
553
 
596
554
  key_ref_length=2;
597
555
  length=mi_getint(page)-key_ref_length;
605
563
    end=page+keys*length;
606
564
    *after_key=end+length;
607
565
    memcpy(key,end,length);
608
 
    DBUG_RETURN(end);
 
566
    return(end);
609
567
  }
610
568
 
611
569
  end= page + length - key_ref_length;
621
579
    {
622
580
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
623
581
      my_errno=HA_ERR_CRASHED;
624
 
      DBUG_RETURN(0);
 
582
      return(0);
625
583
    }
626
584
  }
627
585
  *return_key_length=last_length;
628
586
  *after_key=lastpos;
629
 
  DBUG_PRINT("exit",("returns: 0x%lx  page: 0x%lx  end: 0x%lx",
630
 
                     (long) prevpos,(long) page,(long) end));
631
 
  DBUG_RETURN(prevpos);
 
587
  return(prevpos);
632
588
} /* _mi_find_last_pos */
633
589
 
634
590
 
636
592
        /* returns 0 if balance was done */
637
593
 
638
594
static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
639
 
                            uchar *key, uchar *curr_buff, uchar *father_buff,
640
 
                            uchar *father_key_pos, my_off_t father_page)
 
595
                            unsigned char *key, unsigned char *curr_buff, unsigned char *father_buff,
 
596
                            unsigned char *father_key_pos, my_off_t father_page)
641
597
{
642
 
  my_bool right;
643
 
  uint k_length,father_length,father_keylength,nod_flag,curr_keylength,
 
598
  bool right;
 
599
  uint32_t k_length,father_length,father_keylength,nod_flag,curr_keylength,
644
600
       right_length,left_length,new_right_length,new_left_length,extra_length,
645
601
       length,keys;
646
 
  uchar *pos,*buff,*extra_buff;
 
602
  unsigned char *pos,*buff,*extra_buff;
647
603
  my_off_t next_page,new_pos;
648
 
  uchar tmp_part_key[MI_MAX_KEY_BUFF];
649
 
  DBUG_ENTER("_mi_balance_page");
 
604
  unsigned char tmp_part_key[MI_MAX_KEY_BUFF];
650
605
 
651
606
  k_length=keyinfo->keylength;
652
607
  father_length=mi_getint(father_buff);
663
618
    next_page= _mi_kpos(info->s->base.key_reflength,
664
619
                        father_key_pos+father_keylength);
665
620
    buff=info->buff;
666
 
    DBUG_PRINT("test",("use right page: %lu", (ulong) next_page));
667
621
  }
668
622
  else
669
623
  {
672
626
    next_page= _mi_kpos(info->s->base.key_reflength,father_key_pos);
673
627
                                        /* Fix that curr_buff is to left */
674
628
    buff=curr_buff; curr_buff=info->buff;
675
 
    DBUG_PRINT("test",("use left page: %lu", (ulong) next_page));
676
629
  }                                     /* father_key_pos ptr to parting key */
677
630
 
678
631
  if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
679
632
    goto err;
680
 
  DBUG_DUMP("next",(uchar*) info->buff,mi_getint(info->buff));
681
633
 
682
634
        /* Test if there is room to share keys */
683
635
 
696
648
    if (left_length < new_left_length)
697
649
    {                                           /* Move keys buff -> leaf */
698
650
      pos=curr_buff+left_length;
699
 
      memcpy((uchar*) pos,(uchar*) father_key_pos, (size_t) k_length);
700
 
      memcpy((uchar*) pos+k_length, (uchar*) buff+2,
701
 
             (size_t) (length=new_left_length - left_length - k_length));
 
651
      memcpy(pos, father_key_pos, k_length);
 
652
      length= new_left_length - left_length - k_length;
 
653
      memcpy(pos+k_length, buff+2, length);
702
654
      pos=buff+2+length;
703
 
      memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
704
 
      bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
 
655
      memcpy(father_key_pos, pos, k_length);
 
656
      memcpy(buff+2, pos+k_length, new_right_length);
705
657
    }
706
658
    else
707
659
    {                                           /* Move keys -> buff */
708
660
 
709
 
      bmove_upp((uchar*) buff+new_right_length,(uchar*) buff+right_length,
 
661
      bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
710
662
                right_length-2);
711
663
      length=new_right_length-right_length-k_length;
712
 
      memcpy((uchar*) buff+2+length,father_key_pos,(size_t) k_length);
 
664
      memcpy(buff+2+length,father_key_pos, k_length);
713
665
      pos=curr_buff+new_left_length;
714
 
      memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
715
 
      memcpy((uchar*) buff+2,(uchar*) pos+k_length,(size_t) length);
 
666
      memcpy(father_key_pos, pos, k_length);
 
667
      memcpy(buff+2, pos+k_length, length);
716
668
    }
717
669
 
718
670
    if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
719
671
        _mi_write_keypage(info,keyinfo,father_page,DFLT_INIT_HITS,father_buff))
720
672
      goto err;
721
 
    DBUG_RETURN(0);
 
673
    return(0);
722
674
  }
723
675
 
724
676
        /* curr_buff[] and buff[] are full, lets split and make new nod */
729
681
    new_left_length-=curr_keylength;
730
682
  extra_length=nod_flag+left_length+right_length-
731
683
    new_left_length-new_right_length-curr_keylength;
732
 
  DBUG_PRINT("info",("left_length: %d  right_length: %d  new_left_length: %d  new_right_length: %d  extra_length: %d",
733
 
                     left_length, right_length,
734
 
                     new_left_length, new_right_length,
735
 
                     extra_length));
736
684
  mi_putint(curr_buff,new_left_length,nod_flag);
737
685
  mi_putint(buff,new_right_length,nod_flag);
738
686
  mi_putint(extra_buff,extra_length+2,nod_flag);
739
687
 
740
688
  /* move first largest keys to new page  */
741
689
  pos=buff+right_length-extra_length;
742
 
  memcpy((uchar*) extra_buff+2,pos,(size_t) extra_length);
 
690
  memcpy(extra_buff+2, pos, extra_length);
743
691
  /* Save new parting key */
744
692
  memcpy(tmp_part_key, pos-k_length,k_length);
745
693
  /* Make place for new keys */
746
 
  bmove_upp((uchar*) buff+new_right_length,(uchar*) pos-k_length,
 
694
  bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
747
695
            right_length-extra_length-k_length-2);
748
696
  /* Copy keys from left page */
749
697
  pos= curr_buff+new_left_length;
750
 
  memcpy((uchar*) buff+2,(uchar*) pos+k_length,
751
 
         (size_t) (length=left_length-new_left_length-k_length));
 
698
  length= left_length - new_left_length - k_length;
 
699
  memcpy(buff+2, pos+k_length, length);
752
700
  /* Copy old parting key */
753
 
  memcpy((uchar*) buff+2+length,father_key_pos,(size_t) k_length);
 
701
  memcpy(buff+2+length, father_key_pos, k_length);
754
702
 
755
703
  /* Move new parting keys up to caller */
756
 
  memcpy((uchar*) (right ? key : father_key_pos),pos,(size_t) k_length);
757
 
  memcpy((uchar*) (right ? father_key_pos : key),tmp_part_key, k_length);
 
704
  memcpy((right ? key : father_key_pos), pos, k_length);
 
705
  memcpy((right ? father_key_pos : key), tmp_part_key, k_length);
758
706
 
759
707
  if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
760
708
    goto err;
765
713
                        DFLT_INIT_HITS,extra_buff))
766
714
    goto err;
767
715
 
768
 
  DBUG_RETURN(1);                               /* Middle key up */
 
716
  return(1);                            /* Middle key up */
769
717
 
770
718
err:
771
 
  DBUG_RETURN(-1);
 
719
  return(-1);
772
720
} /* _mi_balance_page */
773
721
 
774
722
/**********************************************************************
777
725
 
778
726
typedef struct {
779
727
  MI_INFO *info;
780
 
  uint keynr;
 
728
  uint32_t keynr;
781
729
} bulk_insert_param;
782
730
 
783
 
int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
784
 
                      uint key_length)
 
731
int _mi_ck_write_tree(register MI_INFO *info, uint32_t keynr, unsigned char *key,
 
732
                      uint32_t key_length)
785
733
{
786
734
  int error;
787
 
  DBUG_ENTER("_mi_ck_write_tree");
788
735
 
789
736
  error= tree_insert(&info->bulk_insert[keynr], key,
790
737
         key_length + info->s->rec_reflength,
791
738
         info->bulk_insert[keynr].custom_arg) ? 0 : HA_ERR_OUT_OF_MEM ;
792
739
 
793
 
  DBUG_RETURN(error);
 
740
  return(error);
794
741
} /* _mi_ck_write_tree */
795
742
 
796
743
 
797
744
/* typeof(_mi_keys_compare)=qsort_cmp2 */
798
745
 
799
 
static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
 
746
static int keys_compare(bulk_insert_param *param, unsigned char *key1, unsigned char *key2)
800
747
{
801
 
  uint not_used[2];
 
748
  uint32_t not_used[2];
802
749
  return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
803
750
                    key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
804
751
                    not_used);
805
752
}
806
753
 
807
754
 
808
 
static int keys_free(uchar *key, TREE_FREE mode, bulk_insert_param *param)
 
755
static int keys_free(unsigned char *key, TREE_FREE mode, bulk_insert_param *param)
809
756
{
810
757
  /*
811
758
    Probably I can use info->lastkey here, but I'm not sure,
812
759
    and to be safe I'd better use local lastkey.
813
760
  */
814
 
  uchar lastkey[MI_MAX_KEY_BUFF];
815
 
  uint keylen;
 
761
  unsigned char lastkey[MI_MAX_KEY_BUFF];
 
762
  uint32_t keylen;
816
763
  MI_KEYDEF *keyinfo;
817
764
 
818
765
  switch (mode) {
838
785
}
839
786
 
840
787
 
841
 
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows)
 
788
int mi_init_bulk_insert(MI_INFO *info, uint32_t cache_size, ha_rows rows)
842
789
{
843
790
  MYISAM_SHARE *share=info->s;
844
791
  MI_KEYDEF *key=share->keyinfo;
845
792
  bulk_insert_param *params;
846
 
  uint i, num_keys, total_keylength;
847
 
  ulonglong key_map;
848
 
  DBUG_ENTER("_mi_init_bulk_insert");
849
 
  DBUG_PRINT("enter",("cache_size: %lu", cache_size));
 
793
  uint32_t i, num_keys, total_keylength;
 
794
  uint64_t key_map;
850
795
 
851
 
  DBUG_ASSERT(!info->bulk_insert &&
 
796
  assert(!info->bulk_insert &&
852
797
              (!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT));
853
798
 
854
799
  mi_clear_all_keys_active(key_map);
865
810
 
866
811
  if (num_keys==0 ||
867
812
      num_keys * MI_MIN_SIZE_BULK_INSERT_TREE > cache_size)
868
 
    DBUG_RETURN(0);
 
813
    return(0);
869
814
 
870
815
  if (rows && rows*total_keylength < cache_size)
871
 
    cache_size= (ulong)rows;
 
816
    cache_size= (uint32_t)rows;
872
817
  else
873
818
    cache_size/=total_keylength*16;
874
819
 
877
822
               sizeof(bulk_insert_param)*num_keys),MYF(0));
878
823
 
879
824
  if (!info->bulk_insert)
880
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
825
    return(HA_ERR_OUT_OF_MEM);
881
826
 
882
827
  params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
883
828
  for (i=0 ; i < share->base.keys ; i++)
897
842
     info->bulk_insert[i].root=0;
898
843
  }
899
844
 
900
 
  DBUG_RETURN(0);
 
845
  return(0);
901
846
}
902
847
 
903
 
void mi_flush_bulk_insert(MI_INFO *info, uint inx)
 
848
void mi_flush_bulk_insert(MI_INFO *info, uint32_t inx)
904
849
{
905
850
  if (info->bulk_insert)
906
851
  {
913
858
{
914
859
  if (info->bulk_insert)
915
860
  {
916
 
    uint i;
 
861
    uint32_t i;
917
862
    for (i=0 ; i < info->s->base.keys ; i++)
918
863
    {
919
864
      if (is_tree_inited(& info->bulk_insert[i]))
921
866
        delete_tree(& info->bulk_insert[i]);
922
867
      }
923
868
    }
924
 
    my_free((void *)info->bulk_insert, MYF(0));
 
869
    free((void *)info->bulk_insert);
925
870
    info->bulk_insert=0;
926
871
  }
927
872
}