~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/archive/ha_archive.cc

  • Committer: Monty Taylor
  • Date: 2008-10-05 01:41:06 UTC
  • Revision ID: monty@inaugust.com-20081005014106-bulqe4kp7i6ipts1
Moved qsort declarations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
  along with this program; if not, write to the Free Software
14
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
 
16
#ifdef USE_PRAGMA_IMPLEMENTATION
 
17
#pragma implementation        // gcc: Class implementation
 
18
#endif
16
19
 
17
20
#include <drizzled/common_includes.h>
18
21
#include <storage/myisam/myisam.h>
98
101
#define ARM ".ARM"               // Meta file (deprecated)
99
102
 
100
103
/*
101
 
  unsigned char + unsigned char
 
104
  uchar + uchar
102
105
*/
103
106
#define DATA_BUFFER_SIZE 2       // Size of the data used in the data file
104
107
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
109
112
                                       MEM_ROOT *mem_root);
110
113
int archive_discover(handlerton *hton, THD* thd, const char *db, 
111
114
                     const char *name,
112
 
                     unsigned char **frmblob, 
 
115
                     uchar **frmblob, 
113
116
                     size_t *frmlen);
114
117
 
115
118
static bool archive_use_aio= false;
134
137
/*
135
138
  Used for hash table that tracks open tables.
136
139
*/
137
 
static unsigned char* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
 
140
static uchar* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
138
141
                             bool not_used __attribute__((unused)))
139
142
{
140
143
  *length=share->table_name_length;
141
 
  return (unsigned char*) share->table_name;
 
144
  return (uchar*) share->table_name;
142
145
}
143
146
 
144
147
 
217
220
                     THD* thd __attribute__((unused)),
218
221
                     const char *db,
219
222
                     const char *name,
220
 
                     unsigned char **frmblob,
 
223
                     uchar **frmblob,
221
224
                     size_t *frmlen)
222
225
{
223
226
  azio_stream frm_stream;
230
233
  if (stat(az_file, &file_stat))
231
234
    goto err;
232
235
 
233
 
  if (!(azopen(&frm_stream, az_file, O_RDONLY, AZ_METHOD_BLOCK)))
 
236
  if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY, AZ_METHOD_BLOCK)))
234
237
  {
235
238
    if (errno == EROFS || errno == EACCES)
236
239
      return(my_errno= errno);
245
248
  azclose(&frm_stream);
246
249
 
247
250
  *frmlen= frm_stream.frm_length;
248
 
  *frmblob= (unsigned char*) frm_ptr;
 
251
  *frmblob= (uchar*) frm_ptr;
249
252
 
250
253
  return(0);
251
254
err:
277
280
*/
278
281
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
279
282
{
280
 
  uint32_t length;
 
283
  uint length;
281
284
 
282
285
  pthread_mutex_lock(&archive_mutex);
283
286
  length=(uint) strlen(table_name);
284
287
 
285
288
  if (!(share=(ARCHIVE_SHARE*) hash_search(&archive_open_tables,
286
 
                                           (unsigned char*) table_name,
 
289
                                           (uchar*) table_name,
287
290
                                           length)))
288
291
  {
289
292
    char *tmp_name;
318
321
      anything but reading... open it for write and we will generate null
319
322
      compression writes).
320
323
    */
321
 
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY,
 
324
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY|O_BINARY,
322
325
                 AZ_METHOD_BLOCK)))
323
326
    {
324
327
      pthread_mutex_destroy(&share->mutex);
337
340
    }
338
341
    azclose(&archive_tmp);
339
342
 
340
 
    my_hash_insert(&archive_open_tables, (unsigned char*) share);
 
343
    my_hash_insert(&archive_open_tables, (uchar*) share);
341
344
    thr_lock_init(&share->lock);
342
345
  }
343
346
  share->use_count++;
360
363
  pthread_mutex_lock(&archive_mutex);
361
364
  if (!--share->use_count)
362
365
  {
363
 
    hash_delete(&archive_open_tables, (unsigned char*) share);
 
366
    hash_delete(&archive_open_tables, (uchar*) share);
364
367
    thr_lock_delete(&share->lock);
365
368
    pthread_mutex_destroy(&share->mutex);
366
369
    /* 
375
378
      if (azclose(&(share->archive_write)))
376
379
        rc= 1;
377
380
    }
378
 
    free((unsigned char*) share);
 
381
    my_free((uchar*) share, MYF(0));
379
382
  }
380
383
  pthread_mutex_unlock(&archive_mutex);
381
384
 
390
393
    that is shared amoung all open tables.
391
394
  */
392
395
  if (!(azopen(&(share->archive_write), share->data_file_name, 
393
 
               O_RDWR, AZ_METHOD_BLOCK)))
 
396
               O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
394
397
  {
395
398
    share->crashed= true;
396
399
    return(1);
426
429
    default:
427
430
      method= AZ_METHOD_BLOCK;
428
431
    }
429
 
    if (!(azopen(&archive, share->data_file_name, O_RDONLY, 
 
432
    if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY, 
430
433
                 method)))
431
434
    {
432
435
      share->crashed= true;
461
464
*/
462
465
int ha_archive::open(const char *name,
463
466
                     int mode __attribute__((unused)),
464
 
                     uint32_t open_options)
 
467
                     uint open_options)
465
468
{
466
469
  int rc= 0;
467
470
  share= get_share(name, &rc);
554
557
  azio_stream create_stream;            /* Archive file we are working with */
555
558
  File frm_file;                   /* File handler for readers */
556
559
  struct stat file_stat;
557
 
  unsigned char *frm_ptr;
 
560
  uchar *frm_ptr;
558
561
 
559
562
  stats.auto_increment_value= create_info->auto_increment_value;
560
563
 
561
 
  for (uint32_t key= 0; key < table_arg->sizeKeys(); key++)
 
564
  for (uint key= 0; key < table_arg->sizeKeys(); key++)
562
565
  {
563
566
    KEY *pos= table_arg->key_info+key;
564
567
    KEY_PART_INFO *key_part=     pos->key_part;
600
603
  if (!stat(name_buff, &file_stat))
601
604
  {
602
605
    my_errno= 0;
603
 
    if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR,
 
606
    if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY,
604
607
                 AZ_METHOD_BLOCK)))
605
608
    {
606
609
      error= errno;
619
622
    {
620
623
      if (fstat(frm_file, &file_stat))
621
624
      {
622
 
        frm_ptr= (unsigned char *)my_malloc(sizeof(unsigned char) * file_stat.st_size, MYF(0));
 
625
        frm_ptr= (uchar *)my_malloc(sizeof(uchar) * file_stat.st_size, MYF(0));
623
626
        if (frm_ptr)
624
627
        {
625
628
          my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
626
629
          azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size);
627
 
          free((unsigned char*)frm_ptr);
 
630
          my_free((uchar*)frm_ptr, MYF(0));
628
631
        }
629
632
      }
630
633
      my_close(frm_file, MYF(0));
661
664
/*
662
665
  This is where the actual row is written out.
663
666
*/
664
 
int ha_archive::real_write_row(unsigned char *buf, azio_stream *writer)
 
667
int ha_archive::real_write_row(uchar *buf, azio_stream *writer)
665
668
{
666
669
  my_off_t written;
667
670
  unsigned int r_pack_length;
687
690
  the bytes required for the length in the header.
688
691
*/
689
692
 
690
 
uint32_t ha_archive::max_row_length(const unsigned char *buf __attribute__((unused)))
 
693
uint32_t ha_archive::max_row_length(const uchar *buf __attribute__((unused)))
691
694
{
692
695
  uint32_t length= (uint32_t)(table->getRecordLength() + table->sizeFields()*2);
693
696
  length+= ARCHIVE_ROW_HEADER_SIZE;
694
697
 
695
 
  uint32_t *ptr, *end;
 
698
  uint *ptr, *end;
696
699
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
697
700
       ptr != end ;
698
701
       ptr++)
704
707
}
705
708
 
706
709
 
707
 
unsigned int ha_archive::pack_row(unsigned char *record)
 
710
unsigned int ha_archive::pack_row(uchar *record)
708
711
{
709
 
  unsigned char *ptr;
 
712
  uchar *ptr;
710
713
 
711
714
  if (fix_rec_buff(max_row_length(record)))
712
715
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
734
737
  for implementing start_bulk_insert() is that we could skip 
735
738
  setting dirty to true each time.
736
739
*/
737
 
int ha_archive::write_row(unsigned char *buf)
 
740
int ha_archive::write_row(uchar *buf)
738
741
{
739
742
  int rc;
740
 
  unsigned char *read_buf= NULL;
 
743
  uchar *read_buf= NULL;
741
744
  uint64_t temp_auto;
742
 
  unsigned char *record=  table->record[0];
 
745
  uchar *record=  table->record[0];
743
746
 
744
747
  if (share->crashed)
745
748
    return(HA_ERR_CRASHED_ON_USAGE);
782
785
        First we create a buffer that we can use for reading rows, and can pass
783
786
        to get_row().
784
787
      */
785
 
      if (!(read_buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
 
788
      if (!(read_buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
786
789
      {
787
790
        rc= HA_ERR_OUT_OF_MEM;
788
791
        goto error;
832
835
error:
833
836
  pthread_mutex_unlock(&share->mutex);
834
837
  if (read_buf)
835
 
    free((unsigned char*) read_buf);
 
838
    my_free((uchar*) read_buf, MYF(0));
836
839
 
837
840
  return(rc);
838
841
}
849
852
}
850
853
 
851
854
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
852
 
int ha_archive::index_init(uint32_t keynr, bool sorted __attribute__((unused)))
 
855
int ha_archive::index_init(uint keynr, bool sorted __attribute__((unused)))
853
856
{
854
857
  active_index= keynr;
855
858
  return(0);
860
863
  No indexes, so if we get a request for an index search since we tell
861
864
  the optimizer that we have unique indexes, we scan
862
865
*/
863
 
int ha_archive::index_read(unsigned char *buf, const unsigned char *key,
864
 
                             uint32_t key_len, enum ha_rkey_function find_flag)
 
866
int ha_archive::index_read(uchar *buf, const uchar *key,
 
867
                             uint key_len, enum ha_rkey_function find_flag)
865
868
{
866
869
  int rc;
867
870
  rc= index_read_idx(buf, active_index, key, key_len, find_flag);
869
872
}
870
873
 
871
874
 
872
 
int ha_archive::index_read_idx(unsigned char *buf, uint32_t index, const unsigned char *key,
873
 
                               uint32_t key_len,
 
875
int ha_archive::index_read_idx(uchar *buf, uint index, const uchar *key,
 
876
                               uint key_len,
874
877
                               enum ha_rkey_function find_flag __attribute__((unused)))
875
878
{
876
879
  int rc;
902
905
}
903
906
 
904
907
 
905
 
int ha_archive::index_next(unsigned char * buf) 
 
908
int ha_archive::index_next(uchar * buf) 
906
909
907
910
  bool found= 0;
908
911
 
946
949
  This is the method that is used to read a row. It assumes that the row is 
947
950
  positioned where you want it.
948
951
*/
949
 
int ha_archive::get_row(azio_stream *file_to_read, unsigned char *buf)
 
952
int ha_archive::get_row(azio_stream *file_to_read, uchar *buf)
950
953
{
951
954
  int rc;
952
955
 
965
968
 
966
969
  if (length > record_buffer->length)
967
970
  {
968
 
    unsigned char *newptr;
969
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*) record_buffer->buffer, 
 
971
    uchar *newptr;
 
972
    if (!(newptr=(uchar*) my_realloc((uchar*) record_buffer->buffer, 
970
973
                                    length,
971
974
                                    MYF(MY_ALLOW_ZERO_PTR))))
972
975
      return(1);
979
982
  return(0);
980
983
}
981
984
 
982
 
int ha_archive::unpack_row(azio_stream *file_to_read, unsigned char *record)
 
985
int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record)
983
986
{
984
987
  unsigned int read;
985
988
  int error;
986
 
  const unsigned char *ptr;
 
989
  const uchar *ptr;
987
990
 
988
991
  read= azread_row(file_to_read, &error);
989
 
  ptr= (const unsigned char *)file_to_read->row_ptr;
 
992
  ptr= (const uchar *)file_to_read->row_ptr;
990
993
 
991
994
  if (error || read == 0)
992
995
  {
1007
1010
}
1008
1011
 
1009
1012
 
1010
 
int ha_archive::get_row_version3(azio_stream *file_to_read, unsigned char *buf)
 
1013
int ha_archive::get_row_version3(azio_stream *file_to_read, uchar *buf)
1011
1014
{
1012
1015
  int returnable= unpack_row(file_to_read, buf);
1013
1016
 
1020
1023
  or by having had ha_archive::rnd_pos() called before it is called.
1021
1024
*/
1022
1025
 
1023
 
int ha_archive::rnd_next(unsigned char *buf)
 
1026
int ha_archive::rnd_next(uchar *buf)
1024
1027
{
1025
1028
  int rc;
1026
1029
 
1047
1050
  needed.
1048
1051
*/
1049
1052
 
1050
 
void ha_archive::position(const unsigned char *record __attribute__((unused)))
 
1053
void ha_archive::position(const uchar *record __attribute__((unused)))
1051
1054
{
1052
1055
  my_store_ptr(ref, ref_length, current_position);
1053
1056
  return;
1061
1064
  correctly ordered row.
1062
1065
*/
1063
1066
 
1064
 
int ha_archive::rnd_pos(unsigned char * buf, unsigned char *pos)
 
1067
int ha_archive::rnd_pos(uchar * buf, uchar *pos)
1065
1068
{
1066
1069
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1067
1070
  current_position= (my_off_t)my_get_ptr(pos, ref_length);
1111
1114
  fn_format(writer_filename, share->table_name, "", ARN, 
1112
1115
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1113
1116
 
1114
 
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR, AZ_METHOD_BLOCK)))
 
1117
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
1115
1118
    return(HA_ERR_CRASHED_ON_USAGE); 
1116
1119
 
1117
1120
  /* 
1255
1258
/*
1256
1259
  Hints for optimizer, see ha_tina for more information
1257
1260
*/
1258
 
int ha_archive::info(uint32_t flag)
 
1261
int ha_archive::info(uint flag)
1259
1262
{
1260
1263
  /* 
1261
1264
    If dirty, we lock, and then reset/flush the data.
1368
1371
  const char *old_proc_info;
1369
1372
  uint64_t x;
1370
1373
 
1371
 
  old_proc_info= get_thd_proc_info(thd);
1372
 
  set_thd_proc_info(thd, "Checking table");
 
1374
  old_proc_info= thd_proc_info(thd, "Checking table");
1373
1375
  /* Flush any waiting data */
1374
1376
  pthread_mutex_lock(&share->mutex);
1375
1377
  azflush(&(share->archive_write), Z_SYNC_FLUSH);
1390
1392
      break;
1391
1393
  }
1392
1394
 
1393
 
  set_thd_proc_info(thd, old_proc_info);
 
1395
  thd_proc_info(thd, old_proc_info);
1394
1396
 
1395
1397
  if ((rc && rc != HA_ERR_END_OF_FILE))  
1396
1398
  {
1426
1428
  }
1427
1429
  r->length= (int)length;
1428
1430
 
1429
 
  if (!(r->buffer= (unsigned char*) my_malloc(r->length,
 
1431
  if (!(r->buffer= (uchar*) my_malloc(r->length,
1430
1432
                                    MYF(MY_WME))))
1431
1433
  {
1432
 
    free((char*) r);
 
1434
    my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
1433
1435
    return(NULL); /* purecov: inspected */
1434
1436
  }
1435
1437
 
1438
1440
 
1439
1441
void ha_archive::destroy_record_buffer(archive_record_buffer *r) 
1440
1442
{
1441
 
  free((char*) r->buffer);
1442
 
  free((char*) r);
 
1443
  my_free((char*) r->buffer, MYF(MY_ALLOW_ZERO_PTR));
 
1444
  my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
1443
1445
  return;
1444
1446
}
1445
1447