30
30
a storage engine without indexes that could compress data very well.
31
31
So, welcome to a completely compressed storage engine. This storage
32
32
engine only does inserts. No replace, deletes, or updates. All reads are
33
- complete table scans. Compression is done through gzip (bzip compresses
33
+ complete table scans. Compression is done through azip (bzip compresses
34
34
better, but only marginally, if someone asks I could add support for
35
- it too, but beaware that it costs a lot more in CPU time then gzip ).
35
+ it too, but beaware that it costs a lot more in CPU time then azip ).
36
36
37
37
We keep a file pointer open for each instance of ha_archive for each read
38
38
but for writes we keep one open file handle just for that. We flush it
39
- only if we have a read occur. gzip handles compressing lots of records
39
+ only if we have a read occur. azip handles compressing lots of records
40
40
at once much better then doing lots of little records between writes.
41
41
It is possible to not lock on writes but this would then mean we couldn't
42
42
handle bulk inserts as well (that is if someone was trying to read at
84
84
Add truncate table command.
85
85
Implement versioning, should be easy.
86
86
Allow for errors, find a way to mark bad rows.
87
- Talk to the gzip guys, come up with a writable format so that updates are doable
87
+ Talk to the azip guys, come up with a writable format so that updates are doable
88
88
without switching to a block method.
89
89
Add optional feature so that rows can be flushed at interval (which will cause less
90
90
compression but may speed up ordered searches).
@@ -256,15 +256,15 @@ ha_archive::ha_archive(TABLE_SHARE *table_arg)
256
256
/*
257
257
This method reads the header of a datafile and returns whether or not it was successful.
258
258
*/
259
- int ha_archive::read_data_header (gzFile file_to_read)
259
+ int ha_archive::read_data_header (azio_stream * file_to_read)
260
260
{
261
261
uchar data_buffer[DATA_BUFFER_SIZE];
262
262
DBUG_ENTER (" ha_archive::read_data_header" );
263
263
264
- if (gzrewind (file_to_read) == -1 )
264
+ if (azrewind (file_to_read) == -1 )
265
265
DBUG_RETURN (HA_ERR_CRASHED_ON_USAGE);
266
266
267
- if (gzread (file_to_read, data_buffer, DATA_BUFFER_SIZE) != DATA_BUFFER_SIZE)
267
+ if (azread (file_to_read, data_buffer, DATA_BUFFER_SIZE) != DATA_BUFFER_SIZE)
268
268
DBUG_RETURN (errno ? errno : -1 );
269
269
270
270
DBUG_PRINT (" ha_archive::read_data_header" , (" Check %u" , data_buffer[0 ]));
@@ -280,15 +280,15 @@ int ha_archive::read_data_header(gzFile file_to_read)
280
280
/*
281
281
This method writes out the header of a datafile and returns whether or not it was successful.
282
282
*/
283
- int ha_archive::write_data_header (gzFile file_to_write)
283
+ int ha_archive::write_data_header (azio_stream * file_to_write)
284
284
{
285
285
uchar data_buffer[DATA_BUFFER_SIZE];
286
286
DBUG_ENTER (" ha_archive::write_data_header" );
287
287
288
288
data_buffer[0 ]= (uchar)ARCHIVE_CHECK_HEADER;
289
289
data_buffer[1 ]= (uchar)ARCHIVE_VERSION;
290
290
291
- if (gzwrite (file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
291
+ if (azwrite (file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
292
292
DATA_BUFFER_SIZE)
293
293
goto error;
294
294
DBUG_PRINT (" ha_archive::write_data_header" , (" Check %u" , (uint )data_buffer[0 ]));
@@ -427,8 +427,11 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
427
427
a gzip file that can be both read and written we keep a writer open
428
428
that is shared amoung all open tables.
429
429
*/
430
- if ((share->archive_write = gzopen (share->data_file_name , " ab" )) == NULL )
430
+ if (!(azopen (&(share->archive_write ), share->data_file_name , O_WRONLY|O_APPEND|O_BINARY)))
431
+ {
432
+ DBUG_PRINT (" info" , (" Could not open archive write file" ));
431
433
share->crashed = TRUE ;
434
+ }
432
435
VOID (my_hash_insert (&archive_open_tables, (byte*) share));
433
436
thr_lock_init (&share->lock );
434
437
}
@@ -453,7 +456,7 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
453
456
thr_lock_delete (&share->lock );
454
457
VOID (pthread_mutex_destroy (&share->mutex ));
455
458
(void )write_meta_file (share->meta_file , share->rows_recorded , FALSE );
456
- if (gzclose ( share->archive_write ) == Z_ERRNO )
459
+ if (azclose (&( share->archive_write )) )
457
460
rc= 1 ;
458
461
if (my_close (share->meta_file , MYF (0 )))
459
462
rc= 1 ;
@@ -494,7 +497,7 @@ int ha_archive::open(const char *name, int mode, uint test_if_locked)
494
497
DBUG_RETURN (HA_ERR_OUT_OF_MEM); // Not handled well by calling code!
495
498
thr_lock_data_init (&share->lock ,&lock,NULL );
496
499
497
- if (( archive= gzopen ( share->data_file_name , " rb " )) == NULL )
500
+ if (!( azopen (& archive, share->data_file_name , O_RDONLY|O_BINARY)) )
498
501
{
499
502
if (errno == EROFS || errno == EACCES)
500
503
DBUG_RETURN (my_errno= errno);
@@ -528,7 +531,7 @@ int ha_archive::close(void)
528
531
DBUG_ENTER (" ha_archive::close" );
529
532
530
533
/* First close stream */
531
- if (gzclose ( archive) == Z_ERRNO )
534
+ if (azclose (& archive))
532
535
rc= 1 ;
533
536
/* then also close share */
534
537
rc|= free_share (share);
@@ -574,18 +577,18 @@ int ha_archive::create(const char *name, TABLE *table_arg,
574
577
error= my_errno;
575
578
goto error;
576
579
}
577
- if (( archive= gzdopen ( create_file, " wb " )) == NULL )
580
+ if (! azdopen (& archive, create_file, O_WRONLY|O_BINARY) )
578
581
{
579
582
error= errno;
580
583
goto error2;
581
584
}
582
- if (write_data_header (archive))
585
+ if (write_data_header (& archive))
583
586
{
584
587
error= errno;
585
588
goto error3;
586
589
}
587
590
588
- if (gzclose ( archive))
591
+ if (azclose (& archive))
589
592
{
590
593
error= errno;
591
594
goto error2;
@@ -596,8 +599,8 @@ int ha_archive::create(const char *name, TABLE *table_arg,
596
599
DBUG_RETURN (0 );
597
600
598
601
error3:
599
- /* We already have an error, so ignore results of gzclose . */
600
- (void )gzclose ( archive);
602
+ /* We already have an error, so ignore results of azclose . */
603
+ (void )azclose (& archive);
601
604
error2:
602
605
my_close (create_file, MYF (0 ));
603
606
delete_table (name);
@@ -609,13 +612,13 @@ int ha_archive::create(const char *name, TABLE *table_arg,
609
612
/*
610
613
This is where the actual row is written out.
611
614
*/
612
- int ha_archive::real_write_row (byte *buf, gzFile writer)
615
+ int ha_archive::real_write_row (byte *buf, azio_stream * writer)
613
616
{
614
617
z_off_t written;
615
618
uint *ptr, *end;
616
619
DBUG_ENTER (" ha_archive::real_write_row" );
617
620
618
- written= gzwrite (writer, buf, table->s ->reclength );
621
+ written= azwrite (writer, buf, table->s ->reclength );
619
622
DBUG_PRINT (" ha_archive::real_write_row" , (" Wrote %d bytes expected %d" , written, table->s ->reclength ));
620
623
if (!delayed_insert || !bulk_insert)
621
624
share->dirty = TRUE ;
@@ -636,7 +639,7 @@ int ha_archive::real_write_row(byte *buf, gzFile writer)
636
639
if (size)
637
640
{
638
641
((Field_blob*) table->field [*ptr])->get_ptr (&data_ptr);
639
- written= gzwrite (writer, data_ptr, (unsigned )size);
642
+ written= azwrite (writer, data_ptr, (unsigned )size);
640
643
if (written != (z_off_t )size)
641
644
DBUG_RETURN (errno ? errno : -1 );
642
645
}
@@ -667,7 +670,7 @@ int ha_archive::write_row(byte *buf)
667
670
table->timestamp_field ->set_time ();
668
671
pthread_mutex_lock (&share->mutex );
669
672
share->rows_recorded ++;
670
- rc= real_write_row (buf, share->archive_write );
673
+ rc= real_write_row (buf, &( share->archive_write ) );
671
674
pthread_mutex_unlock (&share->mutex );
672
675
673
676
DBUG_RETURN (rc);
@@ -694,20 +697,20 @@ int ha_archive::rnd_init(bool scan)
694
697
695
698
/*
696
699
If dirty, we lock, and then reset/flush the data.
697
- I found that just calling gzflush () doesn't always work.
700
+ I found that just calling azflush () doesn't always work.
698
701
*/
699
702
if (share->dirty == TRUE )
700
703
{
701
704
pthread_mutex_lock (&share->mutex );
702
705
if (share->dirty == TRUE )
703
706
{
704
- gzflush ( share->archive_write , Z_SYNC_FLUSH);
707
+ azflush (&( share->archive_write ) , Z_SYNC_FLUSH);
705
708
share->dirty = FALSE ;
706
709
}
707
710
pthread_mutex_unlock (&share->mutex );
708
711
}
709
712
710
- if (read_data_header (archive))
713
+ if (read_data_header (& archive))
711
714
DBUG_RETURN (HA_ERR_CRASHED_ON_USAGE);
712
715
}
713
716
@@ -719,15 +722,15 @@ int ha_archive::rnd_init(bool scan)
719
722
This is the method that is used to read a row. It assumes that the row is
720
723
positioned where you want it.
721
724
*/
722
- int ha_archive::get_row (gzFile file_to_read, byte *buf)
725
+ int ha_archive::get_row (azio_stream * file_to_read, byte *buf)
723
726
{
724
- int read ; // Bytes read, gzread () returns int
727
+ int read ; // Bytes read, azread () returns int
725
728
uint *ptr, *end;
726
729
char *last;
727
730
size_t total_blob_length= 0 ;
728
731
DBUG_ENTER (" ha_archive::get_row" );
729
732
730
- read = gzread (file_to_read, buf, table->s ->reclength );
733
+ read = azread (file_to_read, buf, table->s ->reclength );
731
734
DBUG_PRINT (" ha_archive::get_row" , (" Read %d bytes expected %d" , read , table->s ->reclength ));
732
735
733
736
if (read == Z_STREAM_ERROR)
@@ -762,7 +765,7 @@ int ha_archive::get_row(gzFile file_to_read, byte *buf)
762
765
size_t size= ((Field_blob*) table->field [*ptr])->get_length ();
763
766
if (size)
764
767
{
765
- read = gzread (file_to_read, last, size);
768
+ read = azread (file_to_read, last, size);
766
769
if ((size_t ) read != size)
767
770
DBUG_RETURN (HA_ERR_END_OF_FILE);
768
771
((Field_blob*) table->field [*ptr])->set_ptr (size, last);
@@ -792,8 +795,8 @@ int ha_archive::rnd_next(byte *buf)
792
795
793
796
statistic_increment (table->in_use ->status_var .ha_read_rnd_next_count ,
794
797
&LOCK_status);
795
- current_position= gztell ( archive);
796
- rc= get_row (archive, buf);
798
+ current_position= aztell (& archive);
799
+ rc= get_row (& archive, buf);
797
800
798
801
799
802
if (rc != HA_ERR_END_OF_FILE)
@@ -830,9 +833,9 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
830
833
statistic_increment (table->in_use ->status_var .ha_read_rnd_next_count ,
831
834
&LOCK_status);
832
835
current_position= (z_off_t )my_get_ptr (pos, ref_length);
833
- (void )gzseek ( archive, current_position, SEEK_SET);
836
+ (void )azseek (& archive, current_position, SEEK_SET);
834
837
835
- DBUG_RETURN (get_row (archive, buf));
838
+ DBUG_RETURN (get_row (& archive, buf));
836
839
}
837
840
838
841
/*
@@ -861,17 +864,17 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
861
864
{
862
865
DBUG_ENTER (" ha_archive::optimize" );
863
866
int rc;
864
- gzFile writer;
867
+ azio_stream writer;
865
868
char writer_filename[FN_REFLEN];
866
869
867
870
/* Flush any waiting data */
868
- gzflush ( share->archive_write , Z_SYNC_FLUSH);
871
+ azflush (&( share->archive_write ) , Z_SYNC_FLUSH);
869
872
870
873
/* Lets create a file to contain the new data */
871
874
fn_format (writer_filename, share->table_name , " " , ARN,
872
875
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
873
876
874
- if (( writer= gzopen ( writer_filename, " wb " )) == NULL )
877
+ if (!( azopen (& writer, writer_filename, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY)) )
875
878
DBUG_RETURN (HA_ERR_CRASHED_ON_USAGE);
876
879
877
880
/*
@@ -881,6 +884,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
881
884
882
885
if (check_opt->flags == T_EXTEND)
883
886
{
887
+ DBUG_PRINT (" info" , (" archive extended rebuild" ));
884
888
byte *buf;
885
889
886
890
/*
@@ -897,14 +901,14 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
897
901
Now we will rewind the archive file so that we are positioned at the
898
902
start of the file.
899
903
*/
900
- rc= read_data_header (archive);
904
+ rc= read_data_header (& archive);
901
905
902
906
/*
903
907
Assuming now error from rewinding the archive file, we now write out the
904
908
new header for out data file.
905
909
*/
906
910
if (!rc)
907
- rc= write_data_header (writer);
911
+ rc= write_data_header (& writer);
908
912
909
913
/*
910
914
On success of writing out the new header, we now fetch each row and
@@ -913,9 +917,9 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
913
917
if (!rc)
914
918
{
915
919
share->rows_recorded = 0 ;
916
- while (!(rc= get_row (archive, buf)))
920
+ while (!(rc= get_row (& archive, buf)))
917
921
{
918
- real_write_row (buf, writer);
922
+ real_write_row (buf, & writer);
919
923
share->rows_recorded ++;
920
924
}
921
925
}
@@ -926,31 +930,31 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
926
930
}
927
931
else
928
932
{
933
+ DBUG_PRINT (" info" , (" archive quick rebuild" ));
929
934
/*
930
935
The quick method is to just read the data raw, and then compress it directly.
931
936
*/
932
- int read ; // Bytes read, gzread () returns int
937
+ int read ; // Bytes read, azread () returns int
933
938
char block[IO_SIZE];
934
- if (gzrewind ( archive) == -1 )
939
+ if (azrewind (& archive) == -1 )
935
940
{
936
941
rc= HA_ERR_CRASHED_ON_USAGE;
942
+ DBUG_PRINT (" info" , (" archive HA_ERR_CRASHED_ON_USAGE" ));
937
943
goto error;
938
944
}
939
945
940
- while ((read = gzread ( archive, block, IO_SIZE)))
941
- gzwrite ( writer, block, read );
946
+ while ((read = azread (& archive, block, IO_SIZE)))
947
+ azwrite (& writer, block, read );
942
948
}
943
949
944
- gzflush (writer, Z_SYNC_FLUSH);
945
- gzclose (share->archive_write );
946
- share->archive_write = writer;
950
+ azclose (&writer);
947
951
948
952
my_rename (writer_filename,share->data_file_name ,MYF (0 ));
949
953
950
954
DBUG_RETURN (0 );
951
955
952
956
error:
953
- gzclose ( writer);
957
+ azclose (& writer);
954
958
955
959
DBUG_RETURN (rc);
956
960
}
@@ -1092,7 +1096,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
1092
1096
1093
1097
thd->proc_info = " Checking table" ;
1094
1098
/* Flush any waiting data */
1095
- gzflush ( share->archive_write , Z_SYNC_FLUSH);
1099
+ azflush (&( share->archive_write ) , Z_SYNC_FLUSH);
1096
1100
1097
1101
/*
1098
1102
First we create a buffer that we can use for reading rows, and can pass
@@ -1106,10 +1110,10 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
1106
1110
start of the file.
1107
1111
*/
1108
1112
if (!rc)
1109
- read_data_header (archive);
1113
+ read_data_header (& archive);
1110
1114
1111
1115
if (!rc)
1112
- while (!(rc= get_row (archive, buf)))
1116
+ while (!(rc= get_row (& archive, buf)))
1113
1117
count--;
1114
1118
1115
1119
my_free ((char *)buf, MYF (0 ));
0 commit comments