Below is the list of changes that have just been committed into a local
5.2 repository of rafal. When rafal does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-10-16 10:59:05+02:00, rafal@quant.(none) +3 -0
WL#4063 (Online Backup: Finalize backup stream format)
This patch adds a simple program for testing the backup stream library.
It is not written very carefully and might not work under windows.
It should be improved in the future.
sql/backup/CMakeLists.txt@stripped, 2007-10-16 10:58:57+02:00, rafal@quant.(none) +6 -2
Add definitions of chunk_test program.
sql/backup/Makefile.am@stripped, 2007-10-16 10:58:58+02:00, rafal@quant.(none) +5 -0
Add definitions of chunk_test program.
sql/backup/chunk_test.c@stripped, 2007-10-16 10:58:58+02:00, rafal@quant.(none) +331 -0
Program for testing backup stream library. Note that it is written using
POSIX functions, so it is not sure if it will compile on windows.
sql/backup/chunk_test.c@stripped, 2007-10-16 10:58:58+02:00, rafal@quant.(none) +0 -0
diff -Nrup a/sql/backup/CMakeLists.txt b/sql/backup/CMakeLists.txt
--- a/sql/backup/CMakeLists.txt 2007-10-16 10:44:20 +02:00
+++ b/sql/backup/CMakeLists.txt 2007-10-16 10:58:57 +02:00
@@ -28,7 +28,11 @@ SET(BACKUP_SOURCES stream.cc logger.cc s
be_snapshot.cc)
IF(NOT SOURCE_SUBLIBS)
+
ADD_LIBRARY(backup ${BACKUP_SOURCES})
-ENDIF(NOT SOURCE_SUBLIBS)
+ ADD_LIBRARY(backupstream stream_v1_carrier.c)
-ADD_LIBRARY(backupstream stream_v1_carrier.c)
+ ADD_EXECUTABLE(chunk_test chunk_test.c)
+ TARGET_LINK_LIBRARIES(chunk_test backupstream)
+
+ENDIF(NOT SOURCE_SUBLIBS)
diff -Nrup a/sql/backup/Makefile.am b/sql/backup/Makefile.am
--- a/sql/backup/Makefile.am 2007-10-16 10:44:20 +02:00
+++ b/sql/backup/Makefile.am 2007-10-16 10:58:58 +02:00
@@ -19,6 +19,11 @@
noinst_LTLIBRARIES = libbackup.la libbackupstream.la
+noinst_PROGRAMS = chunk_test
+
+chunk_test_SOURCES = chunk_test.c
+chunk_test_LDADD = libbackupstream.la
+
INCLUDES = \
-I$(top_builddir)/include \
-I$(top_srcdir)/include \
diff -Nrup a/sql/backup/chunk_test.c b/sql/backup/chunk_test.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/sql/backup/chunk_test.c 2007-10-16 10:58:58 +02:00
@@ -0,0 +1,331 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#define BS_USE_MALLOC
+#include "stream_v1.h"
+
+#define ASSERT(X) assert(X)
+
+struct st_stream
+{
+ struct st_backup_stream bs;
+ int fd;
+};
+
+int str_write(struct st_stream *s, bs_blob *data, bs_blob buf)
+{
+ ssize_t howmuch= data->end - data->begin;
+
+ howmuch= write(s->fd,data->begin,howmuch);
+ if (howmuch <= 0)
+ {
+ perror("str_write");
+ return BS_ERROR;
+ }
+
+ data->begin+= howmuch;
+
+ return BS_OK;
+}
+
+int str_read(struct st_stream *s, bs_blob *data, bs_blob envelope)
+{
+ ssize_t howmuch= data->end - data->begin;
+
+ howmuch= read(s->fd, data->begin, howmuch);
+ if (howmuch < 0)
+ {
+ perror("str_read");
+ return BS_ERROR;
+ }
+
+ if (howmuch == 0)
+ return BS_EOS;
+
+ data->begin+= howmuch;
+
+ return BS_OK;
+}
+
+int str_forward(struct st_stream *s, size_t *len)
+{
+ off_t cur_pos= lseek(s->fd,0,SEEK_CUR);
+ off_t off= lseek(s->fd,*len,SEEK_CUR);
+
+ if (off < 0)
+ return BS_ERROR;
+
+ *len= off-cur_pos;
+ return BS_OK;
+}
+
+
+int
+str_open_wr(struct st_stream *s, const char *path, size_t block_size)
+{
+ s->fd= open(path,O_WRONLY|O_CREAT|O_TRUNC,S_IWUSR|S_IRUSR);
+ if (s->fd<0)
+ {
+ perror("str_open_wr");
+ return BS_ERROR;
+ }
+
+ if (block_size==0)
+ block_size= 8;
+
+ s->bs.stream.write= (as_write_m)str_write;
+ s->bs.stream.read= (as_read_m)str_read;
+ s->bs.stream.forward= (as_forward_m)str_forward;
+
+ return bs_open_wr(&s->bs,block_size);
+}
+
+int
+str_open_rd(struct st_stream *s, const char *path, size_t block_size)
+{
+ s->fd= open(path,O_RDONLY);
+ if (s->fd<0)
+ {
+ perror("str_open_rd");
+ return BS_ERROR;
+ }
+
+ s->bs.stream.write= (as_write_m)str_write;
+ s->bs.stream.read= (as_read_m)str_read;
+ s->bs.stream.forward= (as_forward_m)str_forward;
+
+ return bs_open_rd(&s->bs,block_size);
+}
+
+int
+str_close(struct st_stream *s)
+{
+ int ret= bs_close(&s->bs);
+ close(s->fd);
+ return ret;
+}
+
+struct st_stream s;
+
+#define FR_MORE 0x00
+#define FR_LAST 0x40
+#define FR_SMALL_MAX 0x3F
+#define FR_BIG 0x80
+#define FR_HUGE 0xC0
+#define FR_EOC 0x80
+#define FR_EOS 0xC0
+
+bs_byte* show_fragment(bs_byte *ptr, bs_byte *end)
+{
+ bs_byte flags= *(ptr++);
+ size_t len= flags & 0x3F;
+ int last= 1;
+
+ if (flags == FR_EOS)
+ {
+ printf("EOS");
+ return end;
+ }
+
+ if (flags == FR_EOC)
+ {
+ printf("|");
+ return ptr;
+ }
+
+ last= flags & FR_LAST;
+
+ if (len == 0)
+ {
+ len= end-ptr;
+ }
+ else if (flags & 0x80)
+ {
+ last= 0;
+ if ((flags & 0xC0) == FR_BIG)
+ len <<= 6;
+
+ if ((flags & 0xC0) == FR_HUGE)
+ len <<= 12;
+ }
+
+ ptr += len;
+
+ printf("%d%s",len, last ? "|" : ( ptr < end ? "," : "" ));
+
+ return ptr;
+}
+
+int dump_bs_stream(size_t block_size)
+{
+ int ret;
+ bs_byte buf[block_size];
+ bs_blob inp= {buf, buf+block_size };
+ bs_byte *ptr;
+ uint block_no=0;
+
+ do {
+ // read ful block
+ buf[0]= 0x00;
+ ret= as_read_all(&s.bs,inp);
+
+ if (inp.begin == inp.end)
+ return ret;
+
+ ptr= inp.begin;
+
+ printf("block #%-3d [",++block_no);
+
+ do {
+ ptr= show_fragment(ptr,inp.end);
+ } while(ptr && ptr < inp.end);
+
+ printf("]\n");
+
+ } while (ret == BS_OK);
+
+ return ret;
+}
+
+
+void write_chunk(size_t len)
+{
+ static bs_byte buf[]= "1234567890";
+ bs_blob out= {buf,buf+10};
+
+ while (len > 10)
+ {
+ bs_write_blob(&s.bs,out);
+ len -= 10;
+ }
+
+ out.end= buf+len;
+
+ bs_write_blob(&s.bs,out);
+ bs_end_chunk(&s.bs);
+}
+
+int main(int argc, char* argv[])
+{
+ int ret;
+
+ size_t block_size= 0;
+ char line[256], *ptr;
+ bs_blob buf;
+
+ if (argc>1)
+ block_size= atoi(argv[1]);
+
+ ret= str_open_wr(&s,"test.bak",block_size);
+
+ if (ret != BS_OK)
+ {
+ printf("Can't open backup stream (ret=%d)",ret);
+ goto error;
+ }
+
+ block_size= s.bs.block_size;
+ printf("Writting backup stream using blocks of size %d\n",block_size);
+ printf("Enter lines to write (empty line finishes).\n"
+ "Each line will be put in a separate chunk.\n"
+ "Stream will be flushed at sentence boundaries.\n");
+
+ do {
+ fgets(line,sizeof(line),stdin);
+
+ if (line[0] == '\n')
+ {
+ printf("Done reading lines.\n");
+ break;
+ }
+
+ buf.begin= line;
+
+ while (buf.begin)
+ {
+ ptr= buf.begin;
+
+ while ( *ptr != '.' && *ptr != ',' && *ptr != '\n' && *ptr != '\0')
+ ptr++;
+
+ buf.end= ptr + (*ptr == '\n' ? 0 : 1);
+
+ ret= bs_write_blob(&s.bs,buf);
+ if (ret != BS_OK)
+ {
+ printf("Error when writting to the stream (ret=%d)",ret);
+ goto error;
+ }
+
+ if (*ptr == '.')
+ bs_flush(&s.bs);
+
+ buf.begin= *ptr == '\0' || *ptr == '\n' ? NULL : ptr+1;
+ }
+
+ ret= bs_end_chunk(&s.bs);
+ if (ret != BS_OK)
+ {
+ printf("Can't finish a chunk (ret=%d)",ret);
+ goto error;
+ }
+
+ } while (line[0] != '\0');
+
+ bs_flush(&s.bs);
+
+/*
+ int i;
+
+ for (i=1; i<=5; i++)
+ write_chunk(100*i);
+*/
+
+ str_close(&s);
+
+ ret= str_open_rd(&s,"test.bak",block_size);
+
+ if (ret != BS_OK)
+ goto error;
+
+ printf("This is the structure of the stream:\n");
+ dump_bs_stream(block_size);
+ str_close(&s);
+
+ str_open_rd(&s,"test.bak",block_size);
+
+ printf("This is the contents of the stream:\n");
+
+ buf.begin= line;
+ buf.end= line+sizeof(line)-1;
+
+ bs_blob inp;
+
+ do {
+ inp= buf;
+ ret= bs_read_part(&s.bs,&inp,buf);
+ *inp.begin= '\0';
+// printf("read '%s' (%d bytes)\n",line,len);
+ printf("%s",line);
+ if (ret == BS_EOC)
+ {
+// printf("EOC\n");
+ printf("\n");
+ ret= bs_next_chunk(&s.bs);
+ }
+ } while (ret == BS_OK);
+
+ if (ret == BS_ERROR)
+ printf("Error reading backup stream.\n");
+ else
+ printf("\nEnd of stream.\n");
+
+ error:
+
+ str_close(&s);
+
+ return 0;
+}
| Thread |
|---|
| • bk commit into 5.2 tree (rafal:1.2613) | rsomla | 16 Oct |