summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/archive/azio.c147
-rw-r--r--storage/archive/azlib.h13
-rw-r--r--storage/archive/ha_archive.cc62
-rw-r--r--storage/archive/ha_archive.h2
4 files changed, 132 insertions, 92 deletions
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index 8e111f4f50f..8de5ab58702 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -18,6 +18,7 @@
#include <string.h>
static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+static int const az_magic[2] = {0xfe, 0x03}; /* az magic header */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
@@ -66,6 +67,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
s->crc = crc32(0L, Z_NULL, 0);
s->transparent = 0;
s->mode = 'r';
+ s->version = (unsigned char)az_magic[1]; /* this needs to be a define to version */
if (Flags & O_WRONLY || Flags & O_APPEND)
s->mode = 'w';
@@ -112,20 +114,24 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
return Z_NULL;
}
if (s->mode == 'w') {
- char buffer[10];
- /* Write a very simple .gz header:
- */
- buffer[0] = gz_magic[0];
- buffer[1] = gz_magic[1];
- buffer[2] = Z_DEFLATED;
- buffer[3] = 0 /*flags*/;
- buffer[4] = 0;
- buffer[5] = 0;
- buffer[6] = 0;
- buffer[7] = 0 /*time*/;
- buffer[8] = 0 /*xflags*/;
- buffer[9] = 0x03;
- s->start = 10L;
+ char buffer[AZHEADER_SIZE];
+ char *ptr;
+ /* Write a very simple .gz header: */
+ bzero(buffer, AZHEADER_SIZE);
+ buffer[0] = az_magic[0];
+ buffer[1] = az_magic[1];
+ buffer[2] = (unsigned char)0; /* Reserved for block size */
+ buffer[3] = (unsigned char)0; /* Compression Type */
+ ptr= buffer + 4;
+ int4store(ptr, 0LL); /* FRM Block */
+ ptr+= sizeof(unsigned long);
+ int4store(ptr, 0LL); /* Meta Block */
+ ptr+= sizeof(unsigned long);
+ int4store(ptr, (unsigned long)AZHEADER_SIZE); /* Start of Data Block Index Block */
+ ptr+= sizeof(unsigned long);
+
+ s->start = AZHEADER_SIZE;
+ s->version = (unsigned char)az_magic[1];
my_write(s->file, buffer, (uint)s->start, MYF(0));
/* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use
@@ -218,41 +224,53 @@ void check_header(azio_stream *s)
}
/* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
+ if ( s->stream.next_in[0] == gz_magic[0] && s->stream.next_in[1] == gz_magic[1])
+ {
+ s->stream.avail_in -= 2;
+ s->stream.next_in += 2;
+ s->version= (unsigned char)2;
+
+ /* Check the rest of the gzip header */
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
+ else if ( s->stream.next_in[0] == az_magic[0] && s->stream.next_in[1] == az_magic[1])
+ {
+ s->stream.avail_in -= 2;
+ s->stream.next_in += 2;
+ for (len = 0; len < (AZHEADER_SIZE-2); len++) (void)get_byte(s);
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
+ else
+ {
+ s->transparent = 1;
+ s->version = (unsigned char)0;
+ return;
}
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
/* ===========================================================================
@@ -668,10 +686,12 @@ int azclose (azio_stream *s)
if (s == NULL) return Z_STREAM_ERROR;
+
if (s->mode == 'w') {
#ifdef NO_GZCOMPRESS
return Z_STREAM_ERROR;
#else
+
if (do_flush (s, Z_FINISH) != Z_OK)
return destroy(s);
@@ -681,3 +701,42 @@ int azclose (azio_stream *s)
}
return destroy(s);
}
+
+/*
+ This function reads the header of meta block and returns whether or not it was successful.
+ *rows will contain the current number of rows in the data file upon success.
+*/
+int az_read_meta_block(char *meta_start, unsigned long *rows,
+ unsigned long long *auto_increment,
+ unsigned long long *forced_flushes)
+{
+ unsigned char *ptr= meta_start;
+ ulonglong check_point;
+
+ DBUG_ENTER("ha_archive::read_meta_file");
+
+ /*
+ Parse out the meta data, we ignore version at the moment
+ */
+
+ *rows= (unsigned long long)uint8korr(ptr);
+ ptr+= sizeof(unsigned long long); // Move past rows
+ check_point= uint8korr(ptr);
+ ptr+= sizeof(unsigned long long); // Move past check_point
+ *auto_increment= uint8korr(ptr);
+ ptr+= sizeof(unsigned long long); // Move past auto_increment
+ *forced_flushes= uint8korr(ptr);
+ ptr+= sizeof(unsigned long long); // Move past forced_flush
+
+ DBUG_PRINT("ha_archive::read_meta_file", ("Rows %llu",
+ (long long unsigned)*rows));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Checkpoint %llu",
+ (long long unsigned) check_point));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Auto-Increment %llu",
+ (long long unsigned)*auto_increment));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Forced Flushes %llu",
+ (long long unsigned)*forced_flushes));
+ DBUG_PRINT("ha_archive::read_meta_file", ("Dirty %d", (int)(*ptr)));
+
+ DBUG_RETURN(0);
+}
diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h
index 7e20387ff0a..122e460d24c 100644
--- a/storage/archive/azlib.h
+++ b/storage/archive/azlib.h
@@ -1,6 +1,8 @@
/*
This libary has been modified for use by the MySQL Archive Engine.
+ -Brian Aker
*/
+
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.3, July 18th, 2005
@@ -38,6 +40,16 @@
#ifdef __cplusplus
extern "C" {
#endif
+/* Start of MySQL Specific Information */
+
+/*
+ ulonglong + ulonglong + ulonglong + ulonglong + uchar
+*/
+#define AZMETA_BUFFER_SIZE sizeof(ulonglong) \
+ + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) \
+ + sizeof(uchar)
+
+#define AZHEADER_SIZE 16
/*
The 'zlib' compression library provides in-memory compression and
@@ -171,6 +183,7 @@ typedef struct azio_stream {
my_off_t out; /* bytes out of deflate or inflate */
int back; /* one character push-back */
int last; /* true if push-back is last character */
+ unsigned char version; /* Version */
} azio_stream;
/* basic functions */
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 87312331aae..e9d4116459a 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -250,11 +250,17 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
if (azrewind(file_to_read) == -1)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+ if (file_to_read->version >= 3)
+ DBUG_RETURN(0);
+ /* Everything below this is just legacy to version 2< */
+
+ DBUG_PRINT("ha_archive", ("Reading legacy data header"));
+
ret= azread(file_to_read, data_buffer, DATA_BUFFER_SIZE, &error);
if (ret != DATA_BUFFER_SIZE)
{
- DBUG_PRINT("ha_archive", ("Reading, expected %lu got %lu",
+ DBUG_PRINT("ha_archive", ("Reading, expected %d got %lu",
DATA_BUFFER_SIZE, ret));
DBUG_RETURN(1);
}
@@ -268,9 +274,6 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
DBUG_PRINT("ha_archive", ("Check %u", data_buffer[0]));
DBUG_PRINT("ha_archive", ("Version %u", data_buffer[1]));
- share->data_version= (uchar)data_buffer[1];
- DBUG_PRINT("ha_archive", ("Set Version %u", share->data_version));
-
if ((data_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) &&
(data_buffer[1] != (uchar)ARCHIVE_VERSION))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
@@ -279,29 +282,6 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
}
/*
- This method writes out the header of a datafile and returns whether or not it was successful.
-*/
-int ha_archive::write_data_header(azio_stream *file_to_write)
-{
- uchar data_buffer[DATA_BUFFER_SIZE];
- DBUG_ENTER("ha_archive::write_data_header");
-
- data_buffer[0]= (uchar)ARCHIVE_CHECK_HEADER;
- data_buffer[1]= (uchar)ARCHIVE_VERSION;
-
- if (azwrite(file_to_write, &data_buffer, DATA_BUFFER_SIZE) !=
- DATA_BUFFER_SIZE)
- goto error;
- DBUG_PRINT("ha_archive", ("Check %u", (uint)data_buffer[0]));
- DBUG_PRINT("ha_archive", ("Version %u", (uint)data_buffer[1]));
-
- DBUG_RETURN(0);
-error:
- DBUG_PRINT("ha_archive", ("Could not write full data header"));
- DBUG_RETURN(errno);
-}
-
-/*
This method reads the header of a meta file and returns whether or not it was successful.
*rows will contain the current number of rows in the data file upon success.
*/
@@ -616,6 +596,9 @@ int ha_archive::open(const char *name, int mode, uint open_options)
DBUG_RETURN(rc);
}
+ DBUG_ASSERT(share);
+
+
record_buffer= create_record_buffer(table->s->reclength);
if (!record_buffer)
@@ -694,6 +677,7 @@ int ha_archive::create(const char *name, TABLE *table_arg,
File create_file; // We use to create the datafile and the metafile
char name_buff[FN_REFLEN];
int error;
+ azio_stream create_stream; /* Archive file we are working with */
DBUG_ENTER("ha_archive::create");
stats.auto_increment_value= (create_info->auto_increment_value ?
@@ -762,18 +746,13 @@ int ha_archive::create(const char *name, TABLE *table_arg,
goto error;
}
}
- if (!azdopen(&archive, create_file, O_WRONLY|O_BINARY))
+ if (!azdopen(&create_stream, create_file, O_WRONLY|O_BINARY))
{
error= errno;
goto error2;
}
- if (write_data_header(&archive))
- {
- error= errno;
- goto error3;
- }
- if (azclose(&archive))
+ if (azclose(&create_stream))
{
error= errno;
goto error2;
@@ -781,9 +760,6 @@ int ha_archive::create(const char *name, TABLE *table_arg,
DBUG_RETURN(0);
-error3:
- /* We already have an error, so ignore results of azclose. */
- (void)azclose(&archive);
error2:
my_close(create_file, MYF(0));
delete_table(name);
@@ -1140,8 +1116,9 @@ int ha_archive::get_row(azio_stream *file_to_read, byte *buf)
int rc;
DBUG_ENTER("ha_archive::get_row");
DBUG_PRINT("ha_archive", ("Picking version for get_row() %d -> %d",
- share->data_version, ARCHIVE_VERSION));
- if (share->data_version == ARCHIVE_VERSION)
+ (uchar)file_to_read->version,
+ ARCHIVE_VERSION));
+ if (file_to_read->version == ARCHIVE_VERSION)
rc= get_row_version3(file_to_read, buf);
else
rc= get_row_version2(file_to_read, buf);
@@ -1436,13 +1413,6 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
start of the file.
*/
rc= read_data_header(&archive);
-
- /*
- Assuming now error from rewinding the archive file, we now write out the
- new header for out data file.
- */
- if (!rc)
- rc= write_data_header(&writer);
/*
On success of writing out the new header, we now fetch each row and
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index d451cf69488..3e3016cca1e 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -50,7 +50,6 @@ typedef struct st_archive_share {
ulonglong mean_rec_length;
char real_path[FN_REFLEN];
uint meta_version;
- uint data_version;
} ARCHIVE_SHARE;
/*
@@ -137,7 +136,6 @@ public:
int init_archive_writer();
bool auto_repair() const { return 1; } // For the moment we just do this
int read_data_header(azio_stream *file_to_read);
- int write_data_header(azio_stream *file_to_write);
void position(const byte *record);
int info(uint);
void update_create_info(HA_CREATE_INFO *create_info);