MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:June 26 2007 11:47pm
Subject:RE: bk commit into 5.2 tree (rafal:1.2522)
View as plain text  
Rafal,

Patch looks good. Just some general comments.

General Comments (applies to all 4 patches)
-------------------------------------------
I've noticed you don't follow the same doxygen block format everywhere. Some
places have:

/**
  * My comment
  * My comment
  */

While others have:

/**
   My comment
   My comment
  */ 

Which is correct? Please change all comment blocks so they use the same
format. BTW: If the second one is the correct way, let me know so I can
change my code too! ;)

Some single line comments use // instead of /*   */.

Please remove extra *'s from block comments that use the format:

/***********************
  My comment
 ***********************/

Concerns
--------
I was not able to apply the patch to my copy of the tree in either Windows
or Linux. I am concerned because I would have liked to see the compiler
warnings (you know there will be gobs on Windows) so that we could work on
those at each patch rather than trying to fix them all after several patches
are applied. The concern is compounded warnings that could be eliminated
more quickly using more discrete patch application.

Chuck  

> -----Original Message-----
> From: rsomla@stripped [mailto:rsomla@stripped] 
> Sent: Monday, June 25, 2007 5:31 AM
> To: commits@stripped
> Subject: bk commit into 5.2 tree (rafal:1.2522)
> 
> 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-06-25 11:30:29+02:00, rafal@quant.(none) +5 -0
>   WL#3568 (Online backup: Stream format and server file handling):
>     
>   Definition of the interface used for writting/reading 
> backup stream plus
>   basic implementation. Note that the implementation is in 
> prototype stage
>   and has few known limitations which should be removed in the future:
>   - there is hard coded limit on the size of a single data chunk,
>   - data is read/written one chunk at a time regardless of 
> the chunk size.
> 
>   sql/CMakeLists.txt@stripped, 2007-06-25 11:30:26+02:00, 
> rafal@quant.(none) +2 -1
>     Add backup/stream.cc to mysqld sources.
> 
>   sql/Makefile.am@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +3 -2
>     Add backup library to mysqld sources.
> 
>   sql/backup/Makefile.am@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +7 -1
>     Add stream.{h,cc} to backup library.
> 
>   sql/backup/stream.cc@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +325 -0
>     Implementation of backup stream classes.
> 
>   sql/backup/stream.cc@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +0 -0
> 
>   sql/backup/stream.h@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +645 -0
>     - templates for serialization of basic data types,
>     - declarations of backup stream classes.
> 
>   sql/backup/stream.h@stripped, 2007-06-25 11:30:27+02:00, 
> rafal@quant.(none) +0 -0
> 
> # This is a BitKeeper patch.  What follows are the unified 
> diffs for the # set of deltas contained in the patch.  The 
> rest of the patch, the part # that BitKeeper cares about, is 
> below these diffs.
> # User:	rafal
> # Host:	quant.(none)
> # Root:	/ext/mysql/bk/backup/alpha
> 
> --- 1.188/sql/Makefile.am	2007-06-25 11:30:34 +02:00
> +++ 1.189/sql/Makefile.am	2007-06-25 11:30:34 +02:00
> @@ -23,7 +23,7 @@
>  			-I$(top_builddir)/include 
> -I$(top_srcdir)/include \
>  			-I$(top_srcdir)/regex -I$(srcdir) 
> $(openssl_includes)
>  WRAPLIBS=		@WRAPLIBS@
> -SUBDIRS =		share
> +SUBDIRS =		share backup
>  libexec_PROGRAMS =	mysqld
>  EXTRA_PROGRAMS =	gen_lex_hash
>  bin_PROGRAMS =		mysql_tzinfo_to_sql
> @@ -39,7 +39,8 @@
>  			@mysql_plugin_libs@ \
>  			$(LDADD)  $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
>  			$(yassl_libs) $(openssl_libs) \
> -			@MYSQLD_EXTRA_LIBS@
> +			@MYSQLD_EXTRA_LIBS@ \
> +			backup/libbackup.la
>  
>  noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
>  			item_strfunc.h item_timefunc.h \
> 
> --- 1.1/sql/backup/Makefile.am	2007-06-25 11:30:34 +02:00
> +++ 1.2/sql/backup/Makefile.am	2007-06-25 11:30:34 +02:00
> @@ -15,16 +15,22 @@
>  
>  ## Process this file with automake to create Makefile.in
>  
> +noinst_LTLIBRARIES = libbackup.la
> +
>  INCLUDES = \
>  	-I.. \
>  	-I$(top_builddir)/include \
>  	-I$(top_srcdir)/include \
>  	-I$(top_srcdir)/regex
>  
> +libbackup_la_SOURCES = \
> +	stream.cc
> +
>  noinst_HEADERS = \
>  	api_types.h \
>  	backup_engine.h \
> -    debug.h
> +    debug.h \
> +    stream.h
>  
>  DEFS = \
>  	-DMYSQL_SERVER \
> --- New file ---
> +++ sql/backup/stream.cc	07/06/25 11:30:27
> #include "../mysql_priv.h"
> 
> #include "stream.h"
> 
> /*
>   TODO
> 
>   - blocking of OStream output when data window is allocated.
>   - use my_read instead of read - need to know how to detect EOF.
>   - remove fixed chunk size limit (backup::Window::buf_size)
>   - better file buffering (in case of small data chunks)  */
> 
> namespace backup {
> 
> /************** Window *************************/
> 
> Window::Result Window::set_length(const size_t len) {
>   DBUG_ASSERT(!m_blocked);
> 
>   m_end= m_head+len;
> 
>   if (m_end <= last_byte)
>     return stream_result::OK;
> 
>   m_end= last_byte;
>   return out_of_bounds();
> }
> 
> Window::Result Window::move(const off_t offset) {
>   DBUG_ASSERT(!m_blocked);
> 
>   m_head+= offset;
> 
>   if (m_head > m_end)
>     m_end= m_head;
> 
>   if (m_head <= last_byte)
>     return stream_result::OK;
> 
>   m_head= m_end= last_byte;
>   return out_of_bounds();
> }
> 
> /************** Stream *************************/
> 
> bool Stream::open()
> {
>   close();
>   m_fd= my_open(m_path.c_ptr(),m_flags,MYF(0));
>   return m_fd >= 0;
> }
> 
> void Stream::close()
> {
>   if (m_fd >= 0)
>   {
>     my_close(m_fd,MYF(0));
>     m_fd= -1;
>   }
> }
> 
> bool Stream::rewind()
> {
>   return m_fd >= 0 && my_seek(m_fd,0,SEEK_SET,MYF(0)) == 0; }
> 
> 
> /************** OStream *************************/
> 
> /*
>   Implementation of data chunks.
> 
>   Data is written to the file in form of data chunks. Each 
> chunk is prefixed with its size stored
>   in 2 bytes (should it be increased to 4?).
> 
> 
>   OStream instance uses an output buffer of fixed size 
> inherited from Window class. The size of
>   a chunk is limited by the size of this buffer as a whole 
> chunk is stored inside the buffer
>   before writing to the file.
> 
>   writing to the file happens when the current chunk is 
> closed with <code>end_chunk()</code>
>   method. At the time of writing the output, buffer contents 
> is as follows:
> 
>   ====================== <- m_buf
>   2 bytes for chunk size
>   ====================== <- m_buf+2 (chunk data starts here)
> 
>     data written to
>     the chunk
> 
>   ---------------------- <- m_head
> 
>    current output window
> 
>   ====================== <- m_end  (this is end of chunk data)
> 
>  */
> 
> byte* OStream::get_window(const size_t len) {
>   if (m_blocked || m_end+len > last_byte)
>     return NULL;
> 
>   m_head= m_end;
>   m_end+= len;
>   m_blocked= TRUE;
> 
>   return m_head;
> }
> 
> void OStream::drop_window()
> {
>   if (m_blocked)
>    m_end= m_head;
> 
>   m_blocked= FALSE;
> }
> 
> OStream::Result
> OStream::write_window(const size_t len)
> {
>   if (m_blocked)
>   {
>     DBUG_ASSERT(m_head+len<=m_end);
>     m_head+=len;
>     m_end= m_head;
>   }
> 
>   m_blocked= FALSE;
> 
>   return stream_result::OK;
> }
> 
> 
> void OStream::close(bool destroy)
> {
>   if (m_fd<0)
>     return;
> 
>   end_chunk();
> 
>   // write 0 at the end
>   last_byte=m_buf+2;
>   Window::reset();
>   write2int(0);
> 
>   my_write(m_fd,m_buf,2,MYF(0));
> 
>   Stream::close();
> 
>   if (destroy)
>     delete this;
> }
> 
> stream_result::value OStream::end_chunk() {
>   if (m_blocked)
>     drop_window();
> 
>   DBUG_ASSERT(m_end >= m_buf+2);
> 
>   size_t len= m_end - m_buf - 2; // length of the chunk
> 
>   if (len==0)
>   {
>     Window::reset(2);
>     return stream_result::OK;
>   }
> 
>   // store length of chunk in front of the buffer
>   Window::reset();
>   write2int(len);
> 
>   bytes+= len;
> 
>   len+= 2;  // now len is the number of bytes we want to write
> 
>   uint res= my_write(m_fd,m_buf,len,MY_NABP);
> 
>   Window::reset(2);
> 
>   if (res)
>     return stream_result::ERROR;
> 
>   return stream_result::OK;
> }
> 
> /************** IStream *************************/
> 
> /*
>   Handling of stream data chunks.
> 
>   Chunks are read into the input buffer inherited from 
> <code>Window</code> class. It is assumed
>   that a whole chunk will always fit into the buffer 
> (otherwise error is reported).
> 
>   When reading a chunk of data, the size of the next chunk is 
> also read-in in the same file access
>   and stored in the <code>next_chunk_len</code> member.
> 
>   The input buffer has the following layout:
> 
>   =================== <- m_buf (start of input buffer)
> 
>    chunk data
> 
>   ------------------- <- m_head
>    current input
>       window
>   ------------------- <- m_end
> 
>    chunk data
> 
>   =================== <- last_byte  (end of chunk data)
>    size of next chunk
>   =================== <- last_byte+2
> 
>   The first chunk of data is read into the input buffer when 
> stream is opened. Next chunks are
>   read inside <code>next_chunk()</code> method.
> 
>  */
> 
> // PRE: there is at least one chunk in the stream.
> 
> bool IStream::rewind()
> {
>   Stream::rewind();
>   Window::reset();
>   bytes= 0;
> 
>   if (my_read(m_fd, m_buf, 2, MYF(0)) < 2)
>     return FALSE;
> 
>   last_byte= m_head+2;
> 
>   read2int(next_chunk_len);
> 
>   Window::reset();  // ignore the 2 bytes containing chunk length
>   last_byte= m_buf;
> 
>   return next_chunk() == stream_result::OK; }
> 
> stream_result::value IStream::next_chunk() {
>   bytes+= (last_byte-m_buf);    // update statistics
> 
>   last_byte= m_buf;
> 
>   if (next_chunk_len == 0)
>   {
>     Window::reset();
>     return stream_result::EOS;
>   }
> 
>   size_t len= next_chunk_len+2;
> 
>   long int howmuch= 0;  // POSIX ssize_t not defined on win 
> platform :|
> 
>   while (len > 0 && (howmuch= ::read(m_fd,m_buf,len)) > 0)
>     len-= howmuch;
> 
>   if (howmuch<0) // error reading file
>   {
>     next_chunk_len= 0;
>     Window::reset();
>     return stream_result::ERROR;
>   }
> 
>   if (len == 0)
>   {
>     // read length of next chunk (at the end of the buffer)
>     last_byte+= next_chunk_len+2;
>     Window::reset(next_chunk_len);
>     read2int(next_chunk_len);
>     last_byte-=2;
>   }
>   else
>   {
>     last_byte+= next_chunk_len+2-len;
>     next_chunk_len= 0;
>   }
> 
>   Window::reset();
> 
>   return howmuch==0 ? stream_result::EOS : stream_result::OK; }
> 
> #ifdef DBUG_BACKUP
> 
> // Show data chunks in a backup stream;
> 
> void dump_stream(IStream &s)
> {
>   stream_result::value  res;
>   byte b;
> 
>   DBUG_PRINT("stream",("=========="));
> 
>   do {
> 
>     uint chunk_size;
> 
>     for( chunk_size=0; (res= s.readbyte(b)) == 
> stream_result::OK ; ++chunk_size );
> 
>     DBUG_PRINT("stream",(" chunk size= %u",chunk_size));
> 
>     if( res == stream_result::EOC )
>     {
>       DBUG_PRINT("stream",("----------"));
>       res= s.next_chunk();
>     }
> 
>   } while ( res == stream_result::OK );
> 
>   if (res == stream_result::EOS)
>    DBUG_PRINT("stream",("=========="));
>   else
>    DBUG_PRINT("stream",("== ERROR: %d",(int)res)); }
> 
> #endif
> 
> } // backup namespace
> 
> --- New file ---
> +++ sql/backup/stream.h	07/06/25 11:30:27
> #ifndef _BACKUP_STREAM_H_
> #define _BACKUP_STREAM_H_
> 
> #include <backup/api_types.h>    // for Buffer definition
> #include <backup/debug.h>        // for definition of DBUG_BACKUP
> 
> /**
>   @file
> 
>  Generic Stream Interface for serializing basic types 
> (integers, strings etc).
>  */
> 
> namespace util
> {
> 
> typedef unsigned char byte;
> 
> struct stream_result
> {
>   enum value { OK=0, NIL, ERROR };
> };
> 
> 
> /*
>   Stream window: an abstract object which can be used to 
> access a stream
>   of bytes through a window in process address space. The 
> methods give pointer
>   to the beginning of the window and its current size. There 
> is a request for
>   enlarging the window. We can also move the window beginning 
> to the right
>   (decreasing window size). If some bytes move outside the 
> window, they can't
>   be accessed any more.
> 
>   ================================================> (stream of bytes)
> 
>              |--------------------|
>              ^
>              |
>              window header
> 
> 
>   1. Extend window:
> 
>              |--------------------............|
>              ^
>              |
>              window header
> 
>   2. Move window header (shrinks window):
> 
>              .....|---------------|
>                   ^
>                   |
>                   window header
> 
>    Interface
>    ---------
> 
>    typename Result;
> 
>    byte*  head() const;       // pointer to start of the window
>    byte*  end() const;        // pointer to the end of the window
>    size_t length() const;     // current length of the window 
> (in bytes)
>    Result set_length(const size_t size); // extend the window 
> to have (at least) given length
>    Result move(const off_t offset);      // move window header
>    //void  init();
>    //void  done();
> 
>    operator int(const Result&); // interpret the result: is 
> it error or other
>                                    common situation (end of data).
> 
>    Note: window can be used for reading or writing.
> */
> 
> 
> /**
>    Stream classes.
> 
>    These classes provide interface for serializing basic data
>    (numbers, strings) using host independent format.
> 
>    Interface is parametrised by a class implementing stream window.
>    Instance of the window class is used to read/write stream data.
>  */
> 
> template<class SWin>
> class IStream
> {
>   SWin  &m_win;
> 
>  public:
> 
>   typedef typename SWin::Result Result;
> 
>   IStream(SWin &swin): m_win(swin)
>   {}
> 
>   Result readbyte(byte &x);
>   Result read2int(uint &x);
>   Result read4int(ulong &x);
>   Result readint(ulong &x);
>   Result readint(uint &x)
>   {
>     ulong y;
>     Result res= readint(y);
>     x= y;
>     return res;
>   }
> 
>   Result readstr(String &s);
> 
> };
> 
> 
> template<class SWin>
> class OStream
> {
>   SWin &m_win;
> 
>  public:
> 
>   typedef typename SWin::Result Result;
> 
>   OStream(SWin &swin): m_win(swin)
>   {}
> 
>   Result writebyte(const byte x);
>   Result write2int(const int x);
>   Result write4int(const ulong x);
>   Result writeint(const ulong x);
>   Result writestr(const String &s);
>   Result writestr(const char *s)
>   { return writestr(String(s,table_alias_charset)); }
> 
>   Result writenil();
> };
> 
> template<class SW>
> inline
> typename IStream<SW>::Result
> IStream<SW>::readbyte(byte &x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(1)) != stream_result::OK)
>     return res;
> 
>   x= *m_win.head();
> 
>   return m_win.move(1);
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::writebyte(const byte x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(1)) != stream_result::OK)
>     return res;
> 
>   (*m_win.head())= x;
> 
>   return m_win.move(1);
> }
> 
> template<class SW>
> inline
> typename IStream<SW>::Result
> IStream<SW>::read2int(uint &x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(2)) != stream_result::OK)
>    return res;
> 
>   x= uint2korr(m_win.head());
> 
>   return m_win.move(2);
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::write2int(const int x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(2)) != stream_result::OK)
>     return res;
> 
>   int2store(m_win.head(),x);
> 
>   return m_win.move(2);
> }
> 
> 
> template<class SW>
> inline
> typename IStream<SW>::Result
> IStream<SW>::read4int(ulong &x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(4)) != stream_result::OK)
>    return res;
> 
>   x= uint4korr(m_win.head());
> 
>   return m_win.move(4);
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::write4int(const ulong x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(4)) != stream_result::OK)
>     return res;
> 
>   int4store(m_win.head(),x);
> 
>   return m_win.move(4);
> }
> 
> 
> // write/read number using variable-length encoding
> 
> template<class SW>
> inline
> typename IStream<SW>::Result
> IStream<SW>::readint(ulong &x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(1)) != stream_result::OK)
>     return res;
> 
>   x= *m_win.head();
>   m_win.move(1);
> 
>   switch( x ) {
>   case 251:
>     return Result(stream_result::NIL);
> 
>   case 252:
>     uint y;
>     res= read2int(y);
>     x= y;
>     return res;
> 
>   case 253:
>     return read4int(x);
> 
>   default:
>     return Result(stream_result::OK);
>   }
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::writeint(const ulong x)
> {
>   Result res;
> 
>   if ((res= m_win.set_length(1)) != stream_result::OK)
>     return res;
> 
>   if (x < 251)
>     return writebyte((byte)x);
> 
>   if (x < (1UL<<16))
>   {
>     res= writebyte(252);
>     return res == stream_result::OK ? write2int(x) : res;
>   }
> 
>   res= writebyte(253);
>   return res == stream_result::OK ? write4int(x) : res; }
> 
> 
> // Write/read string using "length coded string" format
> 
> template<class SW>
> inline
> typename IStream<SW>::Result
> IStream<SW>::readstr(String &s)
> {
>   Result  res;
>   uint    len;
> 
>   if ((res= readint(len)) != stream_result::OK)
>     return res;
> 
>   if ((res= m_win.set_length(len)) != stream_result::OK)
>     return res;
> 
>   s.free();
>   s.copy((const char*)m_win.head(), len, &::my_charset_bin);
> 
>   return m_win.move(len);
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::writestr(const String &s)
> {
>   Result  res;
>   uint    len= s.length();
> 
>   if ((res= writeint(len)) != stream_result::OK)
>     return res;
> 
>   if ((res= m_win.set_length(len)) != stream_result::OK)
>     return res;
> 
>   memcpy(m_win.head(), s.ptr(), len);
> 
>   return m_win.move(len);
> }
> 
> template<class SW>
> inline
> typename OStream<SW>::Result
> OStream<SW>::writenil()
> {
>   return writebyte(251);
> }
> 
> 
> } // util namespace
> 
> 
> /************************************************************
> 
>   Backup Stream Interface
> 
>   The stream is organized as a sequence of chunks each of which
>   can have different length. When stream is read chunk boundaries
>   are detected. If this happens, next_chunk() member must be called
>   in order to access data in next chunk. When writing to a stream,
>   data is appended to the current chunk. End_chunk() member closes
>   the current chunk and starts a new one.
> 
>  ************************************************************/
> 
> namespace backup {
> 
> struct stream_result
> {
>   enum {
>     OK=    util::stream_result::OK,
>     NIL=   util::stream_result::NIL,
>     ERROR= util::stream_result::ERROR,
>     EOC,    // end of chunk
>     EOS     // end of stream
>   };
> 
>   class value
>   {
>     int m_val;
> 
>    public:
> 
>     value(): m_val(OK) {}
>     value(const int val): m_val(val) {}
> 
>     operator int() { return m_val; }
> 
>     operator result_t()
>     {
>       return m_val == stream_result::ERROR ? backup::ERROR :
>              m_val == stream_result::EOC || m_val == 
> stream_result::EOS ?
>              backup::DONE : backup::OK;
>     }
>   };
> };
> 
> 
> /**
>   Implementation of stream window interface to be used by 
> util::{I,O}Stream
>   templates.
> 
>   It provides a window inside a static data buffer 
> <code>m_buf</code> of
>   fixed size <code>buf_size</code>. The window starts at 
> <code>m_head</code> and ends
>   at <code>m_end</code>. Window can be moved and resized 
> using <code>move()</code>
>   and <code>set_length()</code> methods. These methods take 
> into account
>   size of <code>m_buf</code> and report overflows accordingly.
> 
>   The window can be used by the util::{I,O}Stream templates 
> to read/write
>   basic data types in a uniform, host independent way.
>  */
> 
> class Window
> {
>  public:
> 
>   typedef stream_result::value  Result;
> 
>   byte* head()
>   { return m_head; }
> 
>   byte* end()
>   { return m_end; }
> 
>   size_t length()
>   { return m_end - m_head; }
> 
>   Result set_length(const size_t);  ///< resize window to the 
> given size
>   Result move(const off_t);         ///< move beginning of 
> the window (shrinks size)
> 
>   virtual ~Window() {}
> 
>  protected:
> 
>   Window():
>    last_byte(m_buf+buf_size), m_head(m_buf), m_end(m_buf), 
> m_blocked(FALSE)
>   {}
> 
>   static const size_t buf_size= 4*1024; ///< data buffer size
>   byte  m_buf[buf_size];
> 
>   byte  *last_byte; ///< points at the byte after the last 
> byte of m_buf
>   byte  *m_head;    ///< points at first byte of the current window
>   byte  *m_end;     ///< points at the byte after the last 
> byte of the current window
> 
>   bool  m_blocked;  ///< If true, set_length() and move() are 
> blocked (return ERROR).
> 
>   /// Create empty window at offset in m_buf
>   void reset(off_t offset=0)
>   { m_head= m_end= m_buf+offset; }
> 
>   /// Define the result which should be returned in case of 
> buffer overflow.
>   virtual Result out_of_bounds() const
>   { return stream_result::ERROR; }
> 
>   friend class util::OStream<Window>;
>   friend class util::IStream<Window>;
> };
> 
> } // backup namespace
> 
> 
> template class util::IStream< backup::Window >; template 
> class util::OStream< backup::Window >;
> 
> namespace backup {
> 
> /****************************************************
> 
>    Definitions of input and output backup streams
> 
>  ****************************************************/
> 
> class Stream
> {
>  public:
> 
>   bool open();
>   void close();
>   bool rewind();
> 
>   /// Check if stream is opened
>   operator bool()
>   { return m_fd>0; }
> 
>   ~Stream()
>   { close(); }
> 
>  protected:
> 
>   Stream(const String &name, int flags):
>     m_fd(-1), m_path(name), m_flags(flags) {}
> 
>   int     m_fd;
>   String  m_path;
>   int     m_flags;  ///< flags used when opening the file
> 
> };
> 
> /**
>   Implements backup stream which writes data to a file.
> 
>   This class inherits from util::OStream which defines 
> methods for serialization of
>   basic datatypes (strings and integer). It also implements 
> the concept of data chunks. Data
>   is stored in chunks - writing to an IStream appends data to 
> the current chunk. A chunk is
>   closed and a new one is started with 
> <code>end_chunk()</code> method.
> 
>   A client of this class can ask an instance for an output 
> buffer with <code>get_window()</code>
>   method. After filling the buffer its contents can be 
> written to the stream. This is to avoid
>   double buffering and unnecessary copying of data. However, 
> once an output buffer is allocated,
>   all output to the stream is blocked until the buffer is 
> written with <code>write_window()</code>
>   or dropped with <code>drop_window()</code>.
>  */
> 
> class OStream:
>   Window,
>   public Stream,
>   public util::OStream< Window >
> {
>   typedef util::OStream< Window > Base3;
> 
>  public:
> 
>   typedef stream_result::value Result;  // disambiguate
> 
>   size_t bytes; ///< number of bytes written
> 
>   bool open()
>   {
>     close(FALSE);
>     return Stream::open() && rewind();
>   }
> 
>   void close(bool destroy=TRUE);
> 
>   bool rewind()
>   {
>     Stream::rewind();
>     Window::reset(2);
>     bytes= 0;
>     return TRUE;
>   }
> 
>   Result end_chunk();
> 
>   /**
>     Ask stream for output buffer of given size.
> 
>     If buffer is allocated, stream is blocked for other 
> operations until
>     either write_window() or drop_window() is called.
> 
>     @note Writing to stream using output buffer doesn't create chunks
>     boundaries. Explicit call to end_chunk() is needed.
>    */
>   byte*   get_window(const size_t);
>   Result  write_window(const size_t);
>   void    drop_window();
> 
>   stream_result::value operator <<(const String &str)
>   {
>     return writestr(str);
>   }
> 
>   OStream(const String &name):
>     Stream(name,O_WRONLY|O_CREAT|O_TRUNC),
>     Base3(static_cast<Window&>(*this))
>   {}
> 
> };
> 
> 
> /**
>   Implements backup stream reading data from a file.
> 
>   This class inherits from util::IStream which defines 
> methods for serialization of
>   basic datatypes (strings and integer). It also handles 
> chunk boundaries as created by
>   the OStream class. When reading data at the end of a data 
> chunk, <code>stream_result::EOC</code>
>   is returned. To access data in next chunk, 
> <code>next_chunk()</code> must be called.
>  */
> 
> class IStream:
>   Window,
>   public Stream,
>   public util::IStream< Window >
> {
>   typedef util::IStream< Window > Base3;
> 
>  public:
> 
>   typedef stream_result::value Result;  // disambiguate
> 
>   size_t bytes; ///< number of bytes read
> 
>   bool open()
>   {
>     close(FALSE);
>     return Stream::open() && rewind();
>   }
> 
>   void close(bool destroy=TRUE)
>   {
>     Stream::close();
>     if (destroy)
>       delete this;
>   }
> 
>   bool rewind();
> 
>   Result next_chunk();
> 
>   stream_result::value operator >>(String &str)
>   {
>     return readstr(str);
>   }
> 
>   /**
>     Return current chunk.
> 
>     Will return the same chunk until next_chunk() is called.
>    */
>   stream_result::value operator >>(Buffer &buf)
>   {
>     m_end= last_byte;
> 
>     if (last_byte == m_buf) // empty chunk means end of stream
>       return stream_result::EOS;
> 
>     buf.data= m_buf;
>     buf.size= last_byte - m_buf;
> 
>     return stream_result::OK;
>   }
> 
>   IStream(const String &name):
>     Stream(name,O_RDONLY),
>     Base3(static_cast<Window&>(*this)),
>     bytes(0)
>   { last_byte= m_buf; }
> 
>  private:
> 
>   /// Length of next chunk of data or 0 if there are no more.
>   uint next_chunk_len;  // we use 2 bytes to store chunk len
> 
>   Result out_of_bounds() const
>   { return next_chunk_len > 0 ? stream_result::EOC : 
> stream_result::EOS; }
> 
>   friend class stream_instances;
> };
> 
> #ifdef DBUG_BACKUP
> 
> // Function for debugging backup stream implementation.
> void dump_stream(IStream &);
> 
> #endif
> 
> } // backup namespace
> 
> #endif /*BACKUP_STREAM_H_*/
> 
> 
> --- 1.39/sql/CMakeLists.txt	2007-06-25 11:30:34 +02:00
> +++ 1.40/sql/CMakeLists.txt	2007-06-25 11:30:34 +02:00
> @@ -72,7 +72,8 @@
>                 sql_tablespace.cc events.cc ../sql-common/my_user.c 
>                 partition_info.cc rpl_utility.cc 
> rpl_injector.cc sql_locale.cc
>                 rpl_rli.cc rpl_mi.cc sql_servers.cc
> -	       sql_connect.cc scheduler.cc 
> +               sql_connect.cc scheduler.cc
> +               backup/stream.cc
>                 ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
>    			   ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
>  			   ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
> 
> --
> MySQL Code Commits Mailing List
> For list archives: http://lists.mysql.com/commits
> To unsubscribe:    
> http://lists.mysql.com/commits?unsub=1
> 

Thread
bk commit into 5.2 tree (rafal:1.2522)rsomla25 Jun
  • RE: bk commit into 5.2 tree (rafal:1.2522)Chuck Bell27 Jun