~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_write.c

  • Committer: Brian Aker
  • Date: 2009-02-21 00:18:15 UTC
  • Revision ID: brian@tangent.org-20090221001815-x20e8h71e984lvs1
Completion (?) of uint conversion.

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)
139
144
    not critical to use outdated share->is_log_table value (2) locking
140
145
    mutex here for every write is too expensive.
141
146
  */
142
 
  if (share->is_log_table) // Log table do not exist in Drizzle
143
 
    assert(0);
 
147
  if (share->is_log_table)
 
148
    mi_update_status((void*) info);
144
149
 
145
150
  return(0);
146
151
 
147
152
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)
 
153
  save_errno=my_errno;
 
154
  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
 
155
      my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
151
156
  {
152
157
    if (info->bulk_insert)
153
158
    {
160
165
    {
161
166
      if (mi_is_key_active(share->state.key_map, i))
162
167
      {
 
168
        bool local_lock_tree= (lock_tree &&
 
169
                                  !(info->bulk_insert &&
 
170
                                    is_tree_inited(&info->bulk_insert[i])));
 
171
        if (local_lock_tree)
 
172
          pthread_rwlock_wrlock(&share->key_root_lock[i]);
163
173
        {
164
174
          uint32_t key_length=_mi_make_key(info,i,buff,record,filepos);
165
175
          if (_mi_ck_delete(info,i,buff,key_length))
166
176
          {
 
177
            if (local_lock_tree)
 
178
              pthread_rwlock_unlock(&share->key_root_lock[i]);
167
179
            break;
168
180
          }
169
181
        }
 
182
        if (local_lock_tree)
 
183
          pthread_rwlock_unlock(&share->key_root_lock[i]);
170
184
      }
171
185
    }
172
186
  }
176
190
    mi_mark_crashed(info);
177
191
  }
178
192
  info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
179
 
  errno=save_errno;
 
193
  my_errno=save_errno;
180
194
err2:
181
 
  save_errno=errno;
 
195
  save_errno=my_errno;
182
196
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
183
 
  return(errno=save_errno);
 
197
  return(my_errno=save_errno);
184
198
} /* mi_write */
185
199
 
186
200
 
209
223
  uint32_t error;
210
224
  uint32_t comp_flag;
211
225
  MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
212
 
  internal::my_off_t  *root=&info->s->state.key_root[keynr];
 
226
  my_off_t  *root=&info->s->state.key_root[keynr];
213
227
 
214
228
  if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
215
229
    comp_flag=SEARCH_BIGGER;                    /* Put after same key */
228
242
} /* _mi_ck_write_btree */
229
243
 
230
244
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)
 
245
    unsigned char *key, uint32_t key_length, my_off_t *root, uint32_t comp_flag)
232
246
{
233
247
  int error;
234
248
  /* key_length parameter is used only if comp_flag is SEARCH_FIND */
235
249
  if (*root == HA_OFFSET_ERROR ||
236
250
      (error=w_search(info, keyinfo, comp_flag, key, key_length,
237
251
                      *root, (unsigned char *) 0, (unsigned char*) 0,
238
 
                      (internal::my_off_t) 0, 1)) > 0)
 
252
                      (my_off_t) 0, 1)) > 0)
239
253
    error=_mi_enlarge_root(info,keyinfo,key,root);
240
254
  return(error);
241
255
} /* _mi_ck_real_write_btree */
244
258
        /* Make a new root with key as only pointer */
245
259
 
246
260
int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *key,
247
 
                     internal::my_off_t *root)
 
261
                     my_off_t *root)
248
262
{
249
263
  uint32_t t_length,nod_flag;
250
264
  MI_KEY_PARAM s_temp;
272
286
        */
273
287
 
274
288
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,
 
289
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, my_off_t page,
276
290
                    unsigned char *father_buff, unsigned char *father_keypos,
277
 
                    internal::my_off_t father_page, bool insert_last)
 
291
                    my_off_t father_page, bool insert_last)
278
292
{
279
293
  int error,flag;
280
294
  uint32_t nod_flag, search_key_length;
281
295
  unsigned char *temp_buff,*keypos;
282
296
  unsigned char keybuff[MI_MAX_KEY_BUFF];
283
297
  bool was_last_key;
284
 
  internal::my_off_t next_page, dupp_key_pos;
 
298
  my_off_t next_page, dupp_key_pos;
285
299
 
286
300
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
287
301
  if (!(temp_buff= (unsigned char*) malloc(keyinfo->block_length+
306
320
    {
307
321
      info->dupp_key_pos= dupp_key_pos;
308
322
      free(temp_buff);
309
 
      errno=HA_ERR_FOUND_DUPP_KEY;
 
323
      my_errno=HA_ERR_FOUND_DUPP_KEY;
310
324
      return(-1);
311
325
    }
312
326
  }
359
373
 
360
374
int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
361
375
               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,
 
376
               unsigned char *father_buff, unsigned char *father_key_pos, my_off_t father_page,
363
377
               bool insert_last)
364
378
{
365
379
  uint32_t a_length,nod_flag;
381
395
    if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
382
396
    {
383
397
      mi_print_error(info->s, HA_ERR_CRASHED);
384
 
      errno=HA_ERR_CRASHED;
 
398
      my_errno=HA_ERR_CRASHED;
385
399
      return(-1);
386
400
    }
387
 
    internal::bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
 
401
    bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
388
402
  }
389
403
  else
390
404
  {
391
405
    if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
392
406
    {
393
407
      mi_print_error(info->s, HA_ERR_CRASHED);
394
 
      errno=HA_ERR_CRASHED;
 
408
      my_errno=HA_ERR_CRASHED;
395
409
      return(-1);
396
410
    }
397
411
    memmove(key_pos, key_pos - t_length, endpos - key_pos + t_length);
422
436
{
423
437
  uint32_t length,a_length,key_ref_length,t_length,nod_flag,key_length;
424
438
  unsigned char *key_pos,*pos, *after_key= NULL;
425
 
  internal::my_off_t new_pos;
 
439
  my_off_t new_pos;
426
440
  MI_KEY_PARAM s_temp;
427
441
 
428
442
  if (info->s->keyinfo+info->lastinx == keyinfo)
561
575
    if (!(length=(*keyinfo->get_key)(keyinfo,0,&page,key_buff)))
562
576
    {
563
577
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
564
 
      errno=HA_ERR_CRASHED;
 
578
      my_errno=HA_ERR_CRASHED;
565
579
      return(0);
566
580
    }
567
581
  }
576
590
 
577
591
static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
578
592
                            unsigned char *key, unsigned char *curr_buff, unsigned char *father_buff,
579
 
                            unsigned char *father_key_pos, internal::my_off_t father_page)
 
593
                            unsigned char *father_key_pos, my_off_t father_page)
580
594
{
581
595
  bool right;
582
596
  uint32_t k_length,father_length,father_keylength,nod_flag,curr_keylength,
583
597
       right_length,left_length,new_right_length,new_left_length,extra_length,
584
598
       length,keys;
585
599
  unsigned char *pos,*buff,*extra_buff;
586
 
  internal::my_off_t next_page,new_pos;
 
600
  my_off_t next_page,new_pos;
587
601
  unsigned char tmp_part_key[MI_MAX_KEY_BUFF];
588
602
 
589
603
  k_length=keyinfo->keylength;
641
655
    else
642
656
    {                                           /* Move keys -> buff */
643
657
 
644
 
      internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
 
658
      bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
645
659
                right_length-2);
646
660
      length=new_right_length-right_length-k_length;
647
661
      memcpy(buff+2+length,father_key_pos, k_length);
674
688
  /* Save new parting key */
675
689
  memcpy(tmp_part_key, pos-k_length,k_length);
676
690
  /* Make place for new keys */
677
 
  internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
 
691
  bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
678
692
            right_length-extra_length-k_length-2);
679
693
  /* Copy keys from left page */
680
694
  pos= curr_buff+new_left_length;
749
763
  case free_init:
750
764
    if (param->info->s->concurrent_insert)
751
765
    {
 
766
      pthread_rwlock_wrlock(&param->info->s->key_root_lock[param->keynr]);
752
767
      param->info->s->keyinfo[param->keynr].version++;
753
768
    }
754
769
    return 0;
759
774
    return _mi_ck_write_btree(param->info,param->keynr,lastkey,
760
775
                              keylen - param->info->s->rec_reflength);
761
776
  case free_end:
 
777
    if (param->info->s->concurrent_insert)
 
778
      pthread_rwlock_unlock(&param->info->s->key_root_lock[param->keynr]);
762
779
    return 0;
763
780
  }
764
781
  return -1;
815
832
      init_tree(&info->bulk_insert[i],
816
833
                cache_size * key[i].maxlength,
817
834
                cache_size * key[i].maxlength, 0,
818
 
                (qsort_cmp2)keys_compare, false,
 
835
                (qsort_cmp2)keys_compare, 0,
819
836
                (tree_element_free) keys_free, (void *)params++);
820
837
    }
821
838
    else