~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_write.c

  • Committer: Monty Taylor
  • Date: 2008-12-06 22:41:03 UTC
  • mto: (656.1.7 devel)
  • mto: This revision was merged to the branch mainline in revision 665.
  • Revision ID: monty@inaugust.com-20081206224103-jdouqwt9hb0f01y1
Moved non-working tests into broken suite for easier running of working tests.

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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* Write a row to a MyISAM table */
17
17
 
18
 
#include "myisam_priv.h"
 
18
#include "myisamdef.h"
19
19
 
20
 
#include <drizzled/internal/m_string.h>
 
20
#include <mystrings/m_string.h>
21
21
#include <drizzled/util/test.h>
22
22
 
23
 
using namespace drizzled;
24
23
 
25
24
#define MAX_POINTER_LENGTH 8
26
25
 
28
27
 
29
28
static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,
30
29
                    uint32_t comp_flag, unsigned char *key,
31
 
                    uint32_t key_length, internal::my_off_t pos, unsigned char *father_buff,
32
 
                    unsigned char *father_keypos, internal::my_off_t father_page,
 
30
                    uint32_t key_length, my_off_t pos, unsigned char *father_buff,
 
31
                    unsigned char *father_keypos, my_off_t father_page,
33
32
                    bool insert_last);
34
33
static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
35
34
                            unsigned char *curr_buff,unsigned char *father_buff,
36
 
                            unsigned char *father_keypos,internal::my_off_t father_page);
 
35
                            unsigned char *father_keypos,my_off_t father_page);
37
36
static unsigned char *_mi_find_last_pos(MI_KEYDEF *keyinfo, unsigned char *page,
38
37
                                unsigned char *key, uint32_t *return_key_length,
39
38
                                unsigned char **after_key);
49
48
  MYISAM_SHARE *share=info->s;
50
49
  uint32_t i;
51
50
  int save_errno;
52
 
  internal::my_off_t filepos;
 
51
  my_off_t filepos;
53
52
  unsigned char *buff;
54
53
  bool lock_tree= share->concurrent_insert;
55
54
 
56
55
  if (share->options & HA_OPTION_READ_ONLY_DATA)
57
56
  {
58
 
    return(errno=EACCES);
 
57
    return(my_errno=EACCES);
59
58
  }
60
59
  if (_mi_readinfo(info,F_WRLCK,1))
61
 
    return(errno);
 
60
    return(my_errno);
62
61
  filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
63
62
             !info->append_insert_at_end) ?
64
63
            share->state.dellink :
68
67
      share->base.records == (ha_rows) 1 &&
69
68
      info->state->records == (ha_rows) 1)
70
69
  {                                             /* System file */
71
 
    errno=HA_ERR_RECORD_FILE_FULL;
 
70
    my_errno=HA_ERR_RECORD_FILE_FULL;
72
71
    goto err2;
73
72
  }
74
73
  if (info->state->key_file_length >= share->base.margin_key_file_length)
75
74
  {
76
 
    errno=HA_ERR_INDEX_FILE_FULL;
 
75
    my_errno=HA_ERR_INDEX_FILE_FULL;
77
76
    goto err2;
78
77
  }
79
78
  if (_mi_mark_file_changed(info))
100
99
                                  is_tree_inited(&info->bulk_insert[i])));
101
100
      if (local_lock_tree)
102
101
      {
 
102
        pthread_rwlock_wrlock(&share->key_root_lock[i]);
103
103
        share->keyinfo[i].version++;
104
104
      }
105
105
      {
106
106
        if (share->keyinfo[i].ck_insert(info,i,buff,
107
107
                        _mi_make_key(info,i,buff,record,filepos)))
108
108
        {
 
109
          if (local_lock_tree)
 
110
            pthread_rwlock_unlock(&share->key_root_lock[i]);
109
111
          goto err;
110
112
        }
111
113
      }
112
114
 
113
115
      /* The above changed info->lastkey2. Inform mi_rnext_same(). */
114
116
      info->update&= ~HA_STATE_RNEXT_SAME;
 
117
 
 
118
      if (local_lock_tree)
 
119
        pthread_rwlock_unlock(&share->key_root_lock[i]);
115
120
    }
116
121
  }
117
122
  if (share->calc_checksum)
130
135
  info->state->records++;
131
136
  info->lastpos=filepos;
132
137
  _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
 
138
  if (info->invalidator != 0)
 
139
  {
 
140
    (*info->invalidator)(info->filename);
 
141
    info->invalidator=0;
 
142
  }
133
143
 
134
144
  /*
135
145
    Update status of the table. We need to do so after each row write
139
149
    not critical to use outdated share->is_log_table value (2) locking
140
150
    mutex here for every write is too expensive.
141
151
  */
142
 
  if (share->is_log_table) // Log table do not exist in Drizzle
143
 
    assert(0);
 
152
  if (share->is_log_table)
 
153
    mi_update_status((void*) info);
144
154
 
145
155
  return(0);
146
156
 
147
157
err:
148
 
  save_errno=errno;
149
 
  if (errno == HA_ERR_FOUND_DUPP_KEY || errno == HA_ERR_RECORD_FILE_FULL ||
150
 
      errno == HA_ERR_NULL_IN_SPATIAL || errno == HA_ERR_OUT_OF_MEM)
 
158
  save_errno=my_errno;
 
159
  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
 
160
      my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
151
161
  {
152
162
    if (info->bulk_insert)
153
163
    {
160
170
    {
161
171
      if (mi_is_key_active(share->state.key_map, i))
162
172
      {
 
173
        bool local_lock_tree= (lock_tree &&
 
174
                                  !(info->bulk_insert &&
 
175
                                    is_tree_inited(&info->bulk_insert[i])));
 
176
        if (local_lock_tree)
 
177
          pthread_rwlock_wrlock(&share->key_root_lock[i]);
163
178
        {
164
179
          uint32_t key_length=_mi_make_key(info,i,buff,record,filepos);
165
180
          if (_mi_ck_delete(info,i,buff,key_length))
166
181
          {
 
182
            if (local_lock_tree)
 
183
              pthread_rwlock_unlock(&share->key_root_lock[i]);
167
184
            break;
168
185
          }
169
186
        }
 
187
        if (local_lock_tree)
 
188
          pthread_rwlock_unlock(&share->key_root_lock[i]);
170
189
      }
171
190
    }
172
191
  }
176
195
    mi_mark_crashed(info);
177
196
  }
178
197
  info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
179
 
  errno=save_errno;
 
198
  my_errno=save_errno;
180
199
err2:
181
 
  save_errno=errno;
 
200
  save_errno=my_errno;
182
201
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
183
 
  return(errno=save_errno);
 
202
  return(my_errno=save_errno);
184
203
} /* mi_write */
185
204
 
186
205
 
209
228
  uint32_t error;
210
229
  uint32_t comp_flag;
211
230
  MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
212
 
  internal::my_off_t  *root=&info->s->state.key_root[keynr];
 
231
  my_off_t  *root=&info->s->state.key_root[keynr];
213
232
 
214
233
  if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
215
234
    comp_flag=SEARCH_BIGGER;                    /* Put after same key */
228
247
} /* _mi_ck_write_btree */
229
248
 
230
249
int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo,
231
 
    unsigned char *key, uint32_t key_length, internal::my_off_t *root, uint32_t comp_flag)
 
250
    unsigned char *key, uint32_t key_length, my_off_t *root, uint32_t comp_flag)
232
251
{
233
252
  int error;
234
253
  /* key_length parameter is used only if comp_flag is SEARCH_FIND */
235
254
  if (*root == HA_OFFSET_ERROR ||
236
255
      (error=w_search(info, keyinfo, comp_flag, key, key_length,
237
256
                      *root, (unsigned char *) 0, (unsigned char*) 0,
238
 
                      (internal::my_off_t) 0, 1)) > 0)
 
257
                      (my_off_t) 0, 1)) > 0)
239
258
    error=_mi_enlarge_root(info,keyinfo,key,root);
240
259
  return(error);
241
260
} /* _mi_ck_real_write_btree */
244
263
        /* Make a new root with key as only pointer */
245
264
 
246
265
int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *key,
247
 
                     internal::my_off_t *root)
 
266
                     my_off_t *root)
248
267
{
249
268
  uint32_t t_length,nod_flag;
250
269
  MI_KEY_PARAM s_temp;
272
291
        */
273
292
 
274
293
static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
275
 
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, internal::my_off_t page,
 
294
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, my_off_t page,
276
295
                    unsigned char *father_buff, unsigned char *father_keypos,
277
 
                    internal::my_off_t father_page, bool insert_last)
 
296
                    my_off_t father_page, bool insert_last)
278
297
{
279
298
  int error,flag;
280
299
  uint32_t nod_flag, search_key_length;
281
300
  unsigned char *temp_buff,*keypos;
282
301
  unsigned char keybuff[MI_MAX_KEY_BUFF];
283
302
  bool was_last_key;
284
 
  internal::my_off_t next_page, dupp_key_pos;
 
303
  my_off_t next_page, dupp_key_pos;
285
304
 
286
305
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
287
306
  if (!(temp_buff= (unsigned char*) malloc(keyinfo->block_length+
306
325
    {
307
326
      info->dupp_key_pos= dupp_key_pos;
308
327
      free(temp_buff);
309
 
      errno=HA_ERR_FOUND_DUPP_KEY;
 
328
      my_errno=HA_ERR_FOUND_DUPP_KEY;
310
329
      return(-1);
311
330
    }
312
331
  }
359
378
 
360
379
int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
361
380
               unsigned char *key, unsigned char *anc_buff, unsigned char *key_pos, unsigned char *key_buff,
362
 
               unsigned char *father_buff, unsigned char *father_key_pos, internal::my_off_t father_page,
 
381
               unsigned char *father_buff, unsigned char *father_key_pos, my_off_t father_page,
363
382
               bool insert_last)
364
383
{
365
384
  uint32_t a_length,nod_flag;
381
400
    if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
382
401
    {
383
402
      mi_print_error(info->s, HA_ERR_CRASHED);
384
 
      errno=HA_ERR_CRASHED;
 
403
      my_errno=HA_ERR_CRASHED;
385
404
      return(-1);
386
405
    }
387
 
    internal::bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
 
406
    bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
388
407
  }
389
408
  else
390
409
  {
391
410
    if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
392
411
    {
393
412
      mi_print_error(info->s, HA_ERR_CRASHED);
394
 
      errno=HA_ERR_CRASHED;
 
413
      my_errno=HA_ERR_CRASHED;
395
414
      return(-1);
396
415
    }
397
416
    memmove(key_pos, key_pos - t_length, endpos - key_pos + t_length);
422
441
{
423
442
  uint32_t length,a_length,key_ref_length,t_length,nod_flag,key_length;
424
443
  unsigned char *key_pos,*pos, *after_key= NULL;
425
 
  internal::my_off_t new_pos;
 
444
  my_off_t new_pos;
426
445
  MI_KEY_PARAM s_temp;
427
446
 
428
447
  if (info->s->keyinfo+info->lastinx == keyinfo)
561
580
    if (!(length=(*keyinfo->get_key)(keyinfo,0,&page,key_buff)))
562
581
    {
563
582
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
564
 
      errno=HA_ERR_CRASHED;
 
583
      my_errno=HA_ERR_CRASHED;
565
584
      return(0);
566
585
    }
567
586
  }
576
595
 
577
596
static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
578
597
                            unsigned char *key, unsigned char *curr_buff, unsigned char *father_buff,
579
 
                            unsigned char *father_key_pos, internal::my_off_t father_page)
 
598
                            unsigned char *father_key_pos, my_off_t father_page)
580
599
{
581
600
  bool right;
582
601
  uint32_t k_length,father_length,father_keylength,nod_flag,curr_keylength,
583
602
       right_length,left_length,new_right_length,new_left_length,extra_length,
584
603
       length,keys;
585
604
  unsigned char *pos,*buff,*extra_buff;
586
 
  internal::my_off_t next_page,new_pos;
 
605
  my_off_t next_page,new_pos;
587
606
  unsigned char tmp_part_key[MI_MAX_KEY_BUFF];
588
607
 
589
608
  k_length=keyinfo->keylength;
641
660
    else
642
661
    {                                           /* Move keys -> buff */
643
662
 
644
 
      internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
 
663
      bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
645
664
                right_length-2);
646
665
      length=new_right_length-right_length-k_length;
647
666
      memcpy(buff+2+length,father_key_pos, k_length);
674
693
  /* Save new parting key */
675
694
  memcpy(tmp_part_key, pos-k_length,k_length);
676
695
  /* Make place for new keys */
677
 
  internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
 
696
  bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
678
697
            right_length-extra_length-k_length-2);
679
698
  /* Copy keys from left page */
680
699
  pos= curr_buff+new_left_length;
749
768
  case free_init:
750
769
    if (param->info->s->concurrent_insert)
751
770
    {
 
771
      pthread_rwlock_wrlock(&param->info->s->key_root_lock[param->keynr]);
752
772
      param->info->s->keyinfo[param->keynr].version++;
753
773
    }
754
774
    return 0;
759
779
    return _mi_ck_write_btree(param->info,param->keynr,lastkey,
760
780
                              keylen - param->info->s->rec_reflength);
761
781
  case free_end:
 
782
    if (param->info->s->concurrent_insert)
 
783
      pthread_rwlock_unlock(&param->info->s->key_root_lock[param->keynr]);
762
784
    return 0;
763
785
  }
764
786
  return -1;
798
820
    cache_size/=total_keylength*16;
799
821
 
800
822
  info->bulk_insert=(TREE *)
801
 
    malloc((sizeof(TREE)*share->base.keys+
802
 
           sizeof(bulk_insert_param)*num_keys));
 
823
    my_malloc((sizeof(TREE)*share->base.keys+
 
824
               sizeof(bulk_insert_param)*num_keys),MYF(0));
803
825
 
804
826
  if (!info->bulk_insert)
805
827
    return(HA_ERR_OUT_OF_MEM);
815
837
      init_tree(&info->bulk_insert[i],
816
838
                cache_size * key[i].maxlength,
817
839
                cache_size * key[i].maxlength, 0,
818
 
                (qsort_cmp2)keys_compare, false,
 
840
                (qsort_cmp2)keys_compare, 0,
819
841
                (tree_element_free) keys_free, (void *)params++);
820
842
    }
821
843
    else