diff options
author | unknown <brian@zim.(none)> | 2007-01-11 00:28:22 -0800 |
---|---|---|
committer | unknown <brian@zim.(none)> | 2007-01-11 00:28:22 -0800 |
commit | eb7cd8bd29ada02992d33b6cfe8315733ae61485 (patch) | |
tree | 3d38ced49ec7d2f5f0f933362088714bef685ac6 /storage/archive/azio.c | |
parent | 702a25ddb86c3231bee2a97fae5ddb14067540c2 (diff) | |
parent | 2b3f5085564a7ec77bec921b951d1d4c26f2d212 (diff) | |
download | mariadb-git-eb7cd8bd29ada02992d33b6cfe8315733ae61485.tar.gz |
Merge baker@bk-internal.mysql.com:/home/bk/mysql-5.1-arch
into zim.(none):/home/brian/mysql/archive-format-5.1
storage/archive/Makefile.am:
Auto merged
storage/archive/archive_test.c:
Auto merged
storage/archive/azio.c:
Auto merged
storage/archive/ha_archive.h:
Auto merged
storage/archive/ha_archive.cc:
Merge
Diffstat (limited to 'storage/archive/azio.c')
-rw-r--r-- | storage/archive/azio.c | 336 |
1 files changed, 220 insertions, 116 deletions
diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 4cec83c9518..aa2beb563ee 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -1,12 +1,12 @@ /* azio is a modified version of gzio. It makes use of mysys and removes mallocs. + -Brian Aker */ /* gzio.c -- IO on .gz files * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ /* @(#) $Id$ */ @@ -17,6 +17,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 */ @@ -30,9 +31,11 @@ int az_open(azio_stream *s, const char *path, int Flags, File fd); int do_flush(azio_stream *file, int flush); int get_byte(azio_stream *s); void check_header(azio_stream *s); +void write_header(azio_stream *s); int destroy(azio_stream *s); void putLong(File file, uLong x); uLong getLong(azio_stream *s); +void read_header(azio_stream *s, unsigned char *buffer); /* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter @@ -46,14 +49,14 @@ uLong getLong(azio_stream *s); int az_open (azio_stream *s, const char *path, int Flags, File fd) { int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int level = Z_NO_COMPRESSION; /* Z_DEFAULT_COMPRESSION;*/ /* compression level */ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ s->stream.zalloc = (alloc_func)0; s->stream.zfree = (free_func)0; s->stream.opaque = (voidpf)0; - memset(s->inbuf, 0, Z_BUFSIZE); - memset(s->outbuf, 0, Z_BUFSIZE); + memset(s->inbuf, 0, AZ_BUFSIZE); + memset(s->outbuf, 0, AZ_BUFSIZE); s->stream.next_in = s->inbuf; s->stream.next_out = s->outbuf; s->stream.avail_in = s->stream.avail_out = 0; @@ -65,20 +68,25 @@ 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) + /* + We do our own version of append by nature. + We must always have write access to take card of the header. + */ + DBUG_ASSERT(Flags | O_APPEND); + DBUG_ASSERT(Flags | O_WRONLY); + + if (Flags & O_RDWR) s->mode = 'w'; - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else + if (s->mode == 'w') + { err = deflateInit2(&(s->stream), level, Z_DEFLATED, -MAX_WBITS, 8, strategy); /* windowBits is passed < 0 to suppress zlib header */ s->stream.next_out = s->outbuf; -#endif if (err != Z_OK) { destroy(s); @@ -100,7 +108,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) return Z_NULL; } } - s->stream.avail_out = Z_BUFSIZE; + s->stream.avail_out = AZ_BUFSIZE; errno = 0; s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd; @@ -110,35 +118,64 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) destroy(s); 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; - 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 - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = my_tell(s->file, MYF(0)) - s->stream.avail_in; + + if (Flags & O_CREAT || Flags & O_TRUNC) + { + s->rows= 0; + s->forced_flushes= 0; + s->auto_increment= 0; + s->check_point= 0; + s->dirty= 1; /* We create the file dirty */ + write_header(s); + my_seek(s->file, 0, MY_SEEK_END, MYF(0)); + } + else if (s->mode == 'w') + { + unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE]; + my_pread(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0, MYF(0)); + read_header(s, buffer); /* skip the .az header */ + my_seek(s->file, 0, MY_SEEK_END, MYF(0)); + } + else + { + check_header(s); /* skip the .az header */ } return 1; } + +void write_header(azio_stream *s) +{ + char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE]; + char *ptr= buffer; + + s->start = AZHEADER_SIZE + AZMETA_BUFFER_SIZE; + s->block_size= AZ_BUFSIZE; + s->version = (unsigned char)az_magic[1]; + + + /* Write a very simple .az header: */ + bzero(buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE); + *(ptr + AZ_MAGIC_POS)= az_magic[0]; + *(ptr + AZ_VERSION_POS)= (unsigned char)s->version; + *(ptr + AZ_BLOCK_POS)= (unsigned char)(s->block_size/1024); /* Reserved for block size */ + *(ptr + AZ_STRATEGY_POS)= (unsigned char)Z_DEFAULT_STRATEGY; /* Compression Type */ + + int4store(ptr + AZ_FRM_POS, 0); /* FRM Block */ + int4store(ptr + AZ_META_POS, 0); /* Meta Block */ + int8store(ptr + AZ_START_POS, (unsigned long long)s->start); /* Start of Data Block Index Block */ + printf("ROWS %llu\n", s->rows); + int8store(ptr + AZ_ROW_POS, (unsigned long long)s->rows); /* Start of Data Block Index Block */ + int8store(ptr + AZ_FLUSH_POS, (unsigned long long)s->forced_flushes); /* Start of Data Block Index Block */ + int8store(ptr + AZ_CHECK_POS, (unsigned long long)s->check_point); /* Start of Data Block Index Block */ + int8store(ptr + AZ_AUTOINCREMENT_POS, (unsigned long long)s->auto_increment); /* Start of Data Block Index Block */ + *(ptr + AZ_DIRTY_POS)= (unsigned char)s->dirty; /* Start of Data Block Index Block */ + + /* Always begin at the begining, and end there as well */ + my_pwrite(s->file, buffer, (uint)s->start, 0, MYF(0)); +} + /* =========================================================================== Opens a gzip (.gz) file for reading or writing. */ @@ -170,7 +207,7 @@ int get_byte(s) if (s->stream.avail_in == 0) { errno = 0; - s->stream.avail_in = my_read(s->file, (byte *)s->inbuf, Z_BUFSIZE, MYF(0)); + s->stream.avail_in = my_read(s->file, (byte *)s->inbuf, AZ_BUFSIZE, MYF(0)); if (s->stream.avail_in == 0) { s->z_eof = 1; @@ -206,7 +243,7 @@ void check_header(azio_stream *s) if (len < 2) { if (len) s->inbuf[0] = s->stream.next_in[0]; errno = 0; - len = (uInt)my_read(s->file, (byte *)s->inbuf + len, Z_BUFSIZE >> len, MYF(0)); + len = (uInt)my_read(s->file, (byte *)s->inbuf + len, AZ_BUFSIZE >> len, MYF(0)); if (len == 0) s->z_err = Z_ERRNO; s->stream.avail_in += len; s->stream.next_in = s->inbuf; @@ -217,41 +254,76 @@ 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; + 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; + } - /* 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 & 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; + s->start = my_tell(s->file, MYF(0)) - s->stream.avail_in; + } + else if ( s->stream.next_in[0] == az_magic[0] && s->stream.next_in[1] == az_magic[1]) + { + unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE]; - 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) ; + for (len = 0; len < (AZHEADER_SIZE + AZMETA_BUFFER_SIZE); len++) + buffer[len]= get_byte(s); + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; + read_header(s, buffer); } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; + else + { + s->z_err = Z_OK; + + return; } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; +} + +void read_header(azio_stream *s, unsigned char *buffer) +{ + if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1]) + { + s->version= (unsigned int)buffer[AZ_VERSION_POS]; + s->block_size= 1024 * buffer[AZ_BLOCK_POS]; + s->start= (unsigned long long)uint8korr(buffer + AZ_START_POS); + s->rows= (unsigned long long)uint8korr(buffer + AZ_ROW_POS); + s->check_point= (unsigned long long)uint8korr(buffer + AZ_CHECK_POS); + s->forced_flushes= (unsigned long long)uint8korr(buffer + AZ_FLUSH_POS); + s->auto_increment= (unsigned long long)uint8korr(buffer + AZ_AUTOINCREMENT_POS); + s->dirty= (unsigned int)buffer[AZ_DIRTY_POS]; } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); + else + { + DBUG_ASSERT(buffer[0] == az_magic[0] && buffer[1] == az_magic[1]); + return; } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; } /* =========================================================================== @@ -265,11 +337,7 @@ int destroy (s) if (s->stream.state != NULL) { if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else err = deflateEnd(&(s->stream)); -#endif } else if (s->mode == 'r') { @@ -292,15 +360,28 @@ int destroy (s) Reads the given number of uncompressed bytes from the compressed file. azread returns the number of bytes actually read (0 for end of file). */ -int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned len) +unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned int len, int *error) { Bytef *start = (Bytef*)buf; /* starting point for crc computation */ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + *error= 0; + + if (s->mode != 'r') + { + *error= Z_STREAM_ERROR; + return 0; + } - if (s->mode != 'r') return Z_STREAM_ERROR; + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) + { + *error= s->z_err; + return 0; + } - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + if (s->z_err == Z_STREAM_END) /* EOF */ + { + return 0; + } next_out = (Byte*)buf; s->stream.next_out = (Bytef*)buf; @@ -315,7 +396,9 @@ int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned len) start++; if (s->last) { s->z_err = Z_STREAM_END; - return 1; + { + return 1; + } } } @@ -342,12 +425,14 @@ int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned len) s->in += len; s->out += len; if (len == 0) s->z_eof = 1; - return (int)len; + { + return len; + } } if (s->stream.avail_in == 0 && !s->z_eof) { errno = 0; - s->stream.avail_in = (uInt)my_read(s->file, (byte *)s->inbuf, Z_BUFSIZE, MYF(0)); + s->stream.avail_in = (uInt)my_read(s->file, (byte *)s->inbuf, AZ_BUFSIZE, MYF(0)); if (s->stream.avail_in == 0) { s->z_eof = 1; @@ -374,7 +459,8 @@ int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned len) * Check for such files: */ check_header(s); - if (s->z_err == Z_OK) { + if (s->z_err == Z_OK) + { inflateReset(&(s->stream)); s->crc = crc32(0L, Z_NULL, 0); } @@ -386,34 +472,40 @@ int ZEXPORT azread ( azio_stream *s, voidp buf, unsigned len) if (len == s->stream.avail_out && (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) - return -1; - return (int)(len - s->stream.avail_out); + { + *error= s->z_err; + + return 0; + } + + return (len - s->stream.avail_out); } -#ifndef NO_GZCOMPRESS /* =========================================================================== Writes the given number of uncompressed bytes into the compressed file. azwrite returns the number of bytes actually written (0 in case of error). */ -int azwrite (azio_stream *s, voidpc buf, unsigned len) +unsigned int azwrite (azio_stream *s, voidpc buf, unsigned int len) { - s->stream.next_in = (Bytef*)buf; s->stream.avail_in = len; + + s->rows++; + while (s->stream.avail_in != 0) { if (s->stream.avail_out == 0) { s->stream.next_out = s->outbuf; - if (my_write(s->file, (byte *)s->outbuf, Z_BUFSIZE, MYF(0)) != Z_BUFSIZE) + if (my_write(s->file, (byte *)s->outbuf, AZ_BUFSIZE, MYF(0)) != AZ_BUFSIZE) { s->z_err = Z_ERRNO; break; } - s->stream.avail_out = Z_BUFSIZE; + s->stream.avail_out = AZ_BUFSIZE; } s->in += s->stream.avail_in; s->out += s->stream.avail_out; @@ -424,19 +516,15 @@ int azwrite (azio_stream *s, voidpc buf, unsigned len) } s->crc = crc32(s->crc, (const Bytef *)buf, len); - return (int)(len - s->stream.avail_in); + return (unsigned int)(len - s->stream.avail_in); } -#endif - /* =========================================================================== Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. */ -int do_flush (s, flush) - azio_stream *s; - int flush; +int do_flush (azio_stream *s, int flush) { uInt len; int done = 0; @@ -445,8 +533,9 @@ int do_flush (s, flush) s->stream.avail_in = 0; /* should be zero already anyway */ - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; + for (;;) + { + len = AZ_BUFSIZE - s->stream.avail_out; if (len != 0) { if ((uInt)my_write(s->file, (byte *)s->outbuf, len, MYF(0)) != len) @@ -455,7 +544,7 @@ int do_flush (s, flush) return Z_ERRNO; } s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; + s->stream.avail_out = AZ_BUFSIZE; } if (done) break; s->out += s->stream.avail_out; @@ -472,6 +561,11 @@ int do_flush (s, flush) if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; } + + if (flush == Z_FINISH) + s->dirty= 0; /* Mark it clean, we should be good now */ + write_header(s); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; } @@ -479,11 +573,25 @@ int ZEXPORT azflush (s, flush) azio_stream *s; int flush; { - int err = do_flush (s, flush); + int err; - if (err) return err; - my_sync(s->file, MYF(0)); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; + if (s->mode == 'r') + { + unsigned char buffer[AZHEADER_SIZE + AZMETA_BUFFER_SIZE]; + my_pread(s->file, buffer, AZHEADER_SIZE + AZMETA_BUFFER_SIZE, 0, MYF(0)); + read_header(s, buffer); /* skip the .az header */ + + return Z_OK; + } + else + { + s->forced_flushes++; + err= do_flush(s, flush); + + if (err) return err; + my_sync(s->file, MYF(0)); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; + } } /* =========================================================================== @@ -525,19 +633,17 @@ my_off_t azseek (s, offset, whence) return -1L; } - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { + if (s->mode == 'w') + { + if (whence == SEEK_SET) offset -= s->in; - } /* At this point, offset is the number of zero bytes to write. */ /* There was a zmemzero here if inbuf was null -Brian */ - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; + while (offset > 0) + { + uInt size = AZ_BUFSIZE; + if (offset < AZ_BUFSIZE) size = (uInt)offset; size = azwrite(s, s->inbuf, size); if (size == 0) return -1L; @@ -545,7 +651,6 @@ my_off_t azseek (s, offset, whence) offset -= size; } return s->in; -#endif } /* Rest of function is for reading only */ @@ -580,11 +685,12 @@ my_off_t azseek (s, offset, whence) if (s->last) s->z_err = Z_STREAM_END; } while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; + int error; + unsigned int size = AZ_BUFSIZE; + if (offset < AZ_BUFSIZE) size = (int)offset; - size = azread(s, s->outbuf, (uInt)size); - if (size <= 0) return -1L; + size = azread(s, s->outbuf, size, &error); + if (error <= 0) return -1L; offset -= size; } return s->out; @@ -644,16 +750,14 @@ 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 (s->mode == 'w') + { if (do_flush (s, Z_FINISH) != Z_OK) return destroy(s); putLong(s->file, s->crc); putLong(s->file, (uLong)(s->in & 0xffffffff)); -#endif } return destroy(s); } |