~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_open.cc

  • Committer: Monty Taylor
  • Date: 2009-12-25 08:50:15 UTC
  • mto: This revision was merged to the branch mainline in revision 1255.
  • Revision ID: mordred@inaugust.com-20091225085015-83sux5qsvy312gew
MEM_ROOT == memory::Root

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
/* open a isam-database */
17
17
 
19
19
 
20
20
#include <string.h>
21
21
#include <algorithm>
22
 
#include <memory>
23
 
#include <boost/scoped_ptr.hpp>
24
 
#include <boost/scoped_array.hpp>
25
22
 
26
23
#include "drizzled/charset_info.h"
27
24
#include "drizzled/internal/m_string.h"
32
29
 
33
30
 
34
31
using namespace std;
35
 
using namespace drizzled;
36
32
 
37
33
static void setup_key_functions(MI_KEYDEF *keyinfo);
38
34
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
79
75
  have an open count of 0.
80
76
******************************************************************************/
81
77
 
82
 
MI_INFO *mi_open(const drizzled::identifier::Table &identifier, int mode, uint32_t open_flags)
 
78
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
83
79
{
84
80
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
85
81
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
89
85
  unsigned char *disk_cache= NULL;
90
86
  unsigned char *disk_pos, *end_pos;
91
87
  MI_INFO info,*m_info,*old_info;
92
 
  boost::scoped_ptr<MYISAM_SHARE> share_buff_ap(new MYISAM_SHARE);
93
 
  MYISAM_SHARE &share_buff= *share_buff_ap.get();
94
 
  MYISAM_SHARE *share;
95
 
  boost::scoped_array<ulong> rec_per_key_part_ap(new ulong[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]);
96
 
  ulong *rec_per_key_part= rec_per_key_part_ap.get();
97
 
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
88
  MYISAM_SHARE share_buff,*share;
 
89
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
 
90
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
98
91
  uint64_t max_key_file_length, max_data_file_length;
99
92
 
100
93
  kfile= -1;
103
96
  head_length=sizeof(share_buff.state.header);
104
97
  memset(&info, 0, sizeof(info));
105
98
 
106
 
  (void)internal::fn_format(org_name,
107
 
                            identifier.getPath().c_str(), 
108
 
                            "",
109
 
                            MI_NAME_IEXT,
110
 
                            MY_UNPACK_FILENAME);
 
99
  (void)fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
111
100
  if (!realpath(org_name,rp_buff))
112
 
    internal::my_load_path(rp_buff,org_name, NULL);
 
101
    my_load_path(rp_buff,org_name, NULL);
113
102
  rp_buff[FN_REFLEN-1]= '\0';
114
103
  strcpy(name_buff,rp_buff);
115
 
  THR_LOCK_myisam.lock();
 
104
  pthread_mutex_lock(&THR_LOCK_myisam);
116
105
  if (!(old_info=test_if_reopen(name_buff)))
117
106
  {
118
107
    share= &share_buff;
120
109
    share_buff.state.rec_per_key_part=rec_per_key_part;
121
110
    share_buff.state.key_root=key_root;
122
111
    share_buff.state.key_del=key_del;
123
 
    share_buff.setKeyCache();
 
112
    share_buff.key_cache= dflt_key_cache;
124
113
 
125
 
    if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
114
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
126
115
    {
127
116
      if ((errno != EROFS && errno != EACCES) ||
128
117
          mode != O_RDONLY ||
129
 
          (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
118
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
130
119
        goto err;
131
120
    }
132
121
    share->mode=open_mode;
133
122
    errpos=1;
134
 
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
 
123
    if (my_read(kfile, share->state.header.file_version, head_length,
135
124
                MYF(MY_NABP)))
136
125
    {
137
126
      errno= HA_ERR_NOT_A_TABLE;
143
132
      goto err;
144
133
    }
145
134
    share->options= mi_uint2korr(share->state.header.options);
146
 
    static const uint64_t OLD_FILE_OPTIONS= HA_OPTION_PACK_RECORD |
147
 
            HA_OPTION_PACK_KEYS |
148
 
            HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
149
 
            HA_OPTION_TEMP_COMPRESS_RECORD |
150
 
            HA_OPTION_TMP_TABLE;
151
 
    if (share->options & ~OLD_FILE_OPTIONS)
 
135
    if (share->options &
 
136
        ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
 
137
          HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
 
138
          HA_OPTION_TEMP_COMPRESS_RECORD |
 
139
          HA_OPTION_TMP_TABLE
 
140
          ))
152
141
    {
153
142
      errno=HA_ERR_OLD_FILE;
154
143
      goto err;
161
150
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
162
151
      (void) strcpy(index_name, org_name);
163
152
    *strrchr(org_name, '.')= '\0';
164
 
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
 
153
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
165
154
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
166
155
 
167
156
    info_length=mi_uint2korr(share->state.header.header_length);
176
165
 
177
166
    lseek(kfile,0,SEEK_SET);
178
167
    errpos=3;
179
 
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
 
168
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
180
169
    {
181
170
      errno=HA_ERR_CRASHED;
182
171
      goto err;
233
222
      errno=HA_ERR_UNSUPPORTED;
234
223
      goto err;
235
224
    }
236
 
    share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
237
 
    share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
 
225
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
 
226
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
238
227
 
239
228
    if (share->options & HA_OPTION_COMPRESS_RECORD)
240
229
      share->base.max_key_length+=2;    /* For safety */
257
246
           &share->state.key_root,keys*sizeof(uint64_t),
258
247
           &share->state.key_del,
259
248
           (share->state.header.max_block_size_index*sizeof(uint64_t)),
 
249
           &share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
 
250
           &share->mmap_lock,sizeof(pthread_rwlock_t),
260
251
           NULL))
261
252
      goto err;
262
253
    errpos=4;
264
255
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
265
256
           sizeof(long)*key_parts);
266
257
    memcpy(share->state.key_root, key_root,
267
 
           sizeof(internal::my_off_t)*keys);
 
258
           sizeof(my_off_t)*keys);
268
259
    memcpy(share->state.key_del, key_del,
269
 
           sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
 
260
           sizeof(my_off_t) * share->state.header.max_block_size_index);
270
261
    strcpy(share->unique_file_name, name_buff);
271
262
    share->unique_name_length= strlen(name_buff);
272
263
    strcpy(share->index_file_name,  index_name);
397
388
    disk_cache= NULL;
398
389
    mi_setup_functions(share);
399
390
    share->is_log_table= false;
400
 
    if (myisam_concurrent_insert)
 
391
    thr_lock_init(&share->lock);
 
392
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
 
393
    for (i=0; i<keys; i++)
 
394
      pthread_rwlock_init(&share->key_root_lock[i], NULL);
 
395
    pthread_rwlock_init(&share->mmap_lock, NULL);
 
396
    if (!thr_lock_inited)
 
397
    {
 
398
      /* Probably a single threaded program; Don't use concurrent inserts */
 
399
      myisam_concurrent_insert=0;
 
400
    }
 
401
    else if (myisam_concurrent_insert)
401
402
    {
402
403
      share->concurrent_insert=
403
404
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
406
407
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
407
408
      if (share->concurrent_insert)
408
409
      {
409
 
        assert(0);
 
410
        share->lock.get_status= mi_get_status;
 
411
        share->lock.copy_status= mi_copy_status;
 
412
        share->lock.update_status= mi_update_status;
 
413
        share->lock.restore_status= mi_restore_status;
 
414
        share->lock.check_status= mi_check_status;
410
415
      }
411
416
    }
412
417
  }
432
437
                     share->base.max_key_length),
433
438
         &info.lastkey,share->base.max_key_length*3+1,
434
439
         &info.first_mbr_key, share->base.max_key_length,
435
 
         &info.filename, identifier.getPath().length()+1,
 
440
         &info.filename,strlen(name)+1,
436
441
         &info.rtree_recursion_state,have_rtree ? 1024 : 0,
437
442
         NULL))
438
443
    goto err;
441
446
  if (!have_rtree)
442
447
    info.rtree_recursion_state= NULL;
443
448
 
444
 
  strcpy(info.filename, identifier.getPath().c_str());
 
449
  strcpy(info.filename,name);
445
450
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
446
451
  info.lastkey2=info.lastkey+share->base.max_key_length;
447
452
 
462
467
  info.bulk_insert=0;
463
468
  info.errkey= -1;
464
469
  info.page_changed=1;
 
470
  pthread_mutex_lock(&share->intern_lock);
465
471
  info.read_record=share->read_record;
466
472
  share->reopen++;
467
473
  share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
491
497
 
492
498
  share->delay_key_write= 1;
493
499
  info.state= &share->state.state;      /* Change global values by default */
 
500
  pthread_mutex_unlock(&share->intern_lock);
494
501
 
495
502
  /* Allocate buffer for one record */
496
503
 
497
504
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
498
 
  if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
 
505
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
499
506
    goto err;
500
507
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
501
508
 
502
509
  *m_info=info;
 
510
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
503
511
  myisam_open_list.push_front(m_info);
504
512
 
505
 
  THR_LOCK_myisam.unlock();
 
513
  pthread_mutex_unlock(&THR_LOCK_myisam);
506
514
  return(m_info);
507
515
 
508
516
err:
512
520
  if ((save_errno == HA_ERR_CRASHED) ||
513
521
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
514
522
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
515
 
    mi_report_error(save_errno, identifier.getPath().c_str());
 
523
    mi_report_error(save_errno, name);
516
524
  switch (errpos) {
517
525
  case 6:
518
526
    free((unsigned char*) m_info);
519
527
    /* fall through */
520
528
  case 5:
521
 
    internal::my_close(info.dfile,MYF(0));
 
529
    my_close(info.dfile,MYF(0));
522
530
    if (old_info)
523
531
      break;                                    /* Don't remove open table */
524
532
    /* fall through */
528
536
  case 3:
529
537
    /* fall through */
530
538
  case 1:
531
 
    internal::my_close(kfile,MYF(0));
 
539
    my_close(kfile,MYF(0));
532
540
    /* fall through */
533
541
  case 0:
534
542
  default:
535
543
    break;
536
544
  }
537
 
  THR_LOCK_myisam.unlock();
 
545
  pthread_mutex_unlock(&THR_LOCK_myisam);
538
546
  errno=save_errno;
539
547
  return (NULL);
540
548
} /* mi_open */
550
558
    unsigned char *newptr = *buf;
551
559
 
552
560
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
553
 
    if (length == SIZE_MAX)
 
561
    if (length == (ulong) -1)
554
562
    {
555
563
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
556
564
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
580
588
 
581
589
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
582
590
{
583
 
  uint64_t max_val= ~ (uint64_t) 0;             /* internal::my_off_t is unsigned */
 
591
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
584
592
 
585
593
  if (!a || max_val / a < b)
586
594
    return max_val;
745
753
  if (pWrite & 1)
746
754
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
747
755
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
748
 
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
 
756
  return(my_write(file, buff, (size_t) (ptr-buff),
749
757
                       MYF(MY_NABP)) != 0);
750
758
}
751
759
 
771
779
  state->state.empty    = mi_sizekorr(ptr);     ptr +=8;
772
780
  state->state.key_empty= mi_sizekorr(ptr);     ptr +=8;
773
781
  state->auto_increment=mi_uint8korr(ptr);      ptr +=8;
774
 
  state->state.checksum=(internal::ha_checksum) mi_uint8korr(ptr);      ptr +=8;
 
782
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);        ptr +=8;
775
783
  state->process= mi_uint4korr(ptr);            ptr +=4;
776
784
  state->unique = mi_uint4korr(ptr);            ptr +=4;
777
785
  state->status = mi_uint4korr(ptr);            ptr +=4;
812
820
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
813
821
      return 1;
814
822
  }
815
 
  else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
 
823
  else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
816
824
    return 1;
817
825
  mi_state_info_read(buff, state);
818
826
 
857
865
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
858
866
 
859
867
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
860
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
868
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
861
869
}
862
870
 
863
871
 
911
919
  mi_int2store(ptr,keydef->keylength);          ptr +=2;
912
920
  mi_int2store(ptr,keydef->minlength);          ptr +=2;
913
921
  mi_int2store(ptr,keydef->maxlength);          ptr +=2;
914
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
922
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
915
923
}
916
924
 
917
925
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
953
961
  mi_int4store(ptr, pos);
954
962
  ptr+=4;
955
963
 
956
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
964
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
957
965
}
958
966
 
959
967
 
993
1001
  *ptr++=  (unsigned char) def->key;
994
1002
  *ptr++ = (unsigned char) def->null_are_equal;
995
1003
 
996
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1004
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
997
1005
}
998
1006
 
999
1007
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1017
1025
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1018
1026
  *ptr++ = recinfo->null_bit;
1019
1027
  mi_int2store(ptr,recinfo->null_pos);  ptr+= 2;
1020
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1028
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1021
1029
}
1022
1030
 
1023
1031
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1041
1049
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
1042
1050
{
1043
1051
  (void)file_to_dup; 
1044
 
  info->dfile=internal::my_open(share->data_file_name, share->mode,
 
1052
  info->dfile=my_open(share->data_file_name, share->mode,
1045
1053
                      MYF(MY_WME));
1046
1054
  return info->dfile >= 0 ? 0 : 1;
1047
1055
}
1049
1057
 
1050
1058
int mi_open_keyfile(MYISAM_SHARE *share)
1051
1059
{
1052
 
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
 
1060
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
1053
1061
                            MYF(MY_WME))) < 0)
1054
1062
    return 1;
1055
1063
  return 0;