Drizzled Public API Documentation

iocache.h
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 MySQL
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #pragma once
00022 
00023 #include <drizzled/internal/my_sys.h>
00024 
00025 namespace drizzled {
00026 namespace internal {
00027 
00028 #define my_b_EOF INT_MIN
00029 
00030 class io_cache_st    /* Used when cacheing files */
00031 {
00032 public:
00033   typedef int (*IO_CACHE_CALLBACK)(io_cache_st*);
00034 
00035   /* Offset in file corresponding to the first byte of unsigned char* buffer. */
00036   my_off_t pos_in_file;
00037   /*
00038     The offset of end of file for READ_CACHE and WRITE_CACHE.
00039     For SEQ_READ_APPEND it the maximum of the actual end of file and
00040     the position represented by read_end.
00041   */
00042   my_off_t end_of_file;
00043   /* Points to current read position in the buffer */
00044   unsigned char  *read_pos;
00045   /* the non-inclusive boundary in the buffer for the currently valid read */
00046   unsigned char  *read_end;
00047   unsigned char  *buffer;        /* The read buffer */
00048   /* Used in ASYNC_IO */
00049   unsigned char  *request_pos;
00050 
00051   /* Only used in WRITE caches and in SEQ_READ_APPEND to buffer writes */
00052   unsigned char  *write_buffer;
00053   /*
00054     Only used in SEQ_READ_APPEND, and points to the current read position
00055     in the write buffer. Note that reads in SEQ_READ_APPEND caches can
00056     happen from both read buffer (unsigned char* buffer) and write buffer
00057     (unsigned char* write_buffer).
00058   */
00059   unsigned char *append_read_pos;
00060   /* Points to current write position in the write buffer */
00061   unsigned char *write_pos;
00062   /* The non-inclusive boundary of the valid write area */
00063   unsigned char *write_end;
00064 
00065   /*
00066     Current_pos and current_end are convenience variables used by
00067     my_b_tell() and other routines that need to know the current offset
00068     current_pos points to &write_pos, and current_end to &write_end in a
00069     WRITE_CACHE, and &read_pos and &read_end respectively otherwise
00070   */
00071   unsigned char  **current_pos, **current_end;
00072   /*
00073     A caller will use my_b_read() macro to read from the cache
00074     if the data is already in cache, it will be simply copied with
00075     memcpy() and internal variables will be accordinging updated with
00076     no functions invoked. However, if the data is not fully in the cache,
00077     my_b_read() will call read_function to fetch the data. read_function
00078     must never be invoked directly.
00079   */
00080   int (*read_function)(io_cache_st* ,unsigned char *,size_t);
00081   /*
00082     Same idea as in the case of read_function, except my_b_write() needs to
00083     be replaced with my_b_append() for a SEQ_READ_APPEND cache
00084   */
00085   int (*write_function)(io_cache_st* ,const unsigned char *,size_t);
00086   /*
00087     Specifies the type of the cache. Depending on the type of the cache
00088     certain operations might not be available and yield unpredicatable
00089     results. Details to be documented later
00090   */
00091   cache_type type;
00092   int error;
00093   /*
00094     Callbacks when the actual read I/O happens. These were added and
00095     are currently used for binary logging of LOAD DATA INFILE - when a
00096     block is read from the file, we create a block create/append event, and
00097     when io_cache_st is closed, we create an end event. These functions could,
00098     of course be used for other things
00099   */
00100   IO_CACHE_CALLBACK pre_read;
00101   IO_CACHE_CALLBACK post_read;
00102   IO_CACHE_CALLBACK pre_close;
00103   void* arg;        /* for use by pre/post_read */
00104   char *file_name;      /* if used with 'open_cached_file' */
00105   char *dir,*prefix;
00106   int file; /* file descriptor */
00107   /*
00108     seek_not_done is set by my_b_seek() to inform the upcoming read/write
00109     operation that a seek needs to be preformed prior to the actual I/O
00110     error is 0 if the cache operation was successful, -1 if there was a
00111     "hard" error, and the actual number of I/O-ed bytes if the read/write was
00112     partial.
00113   */
00114   int  seek_not_done;
00115   /* buffer_length is memory size allocated for buffer or write_buffer */
00116   size_t  buffer_length;
00117   /* read_length is the same as buffer_length except when we use async io */
00118   size_t  read_length;
00119   myf  myflags;      /* Flags used to my_read/my_write */
00120   /*
00121     alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
00122     0 if it was supplied by the user.
00123     Currently READ_NET is the only one that will use a buffer allocated
00124     somewhere else
00125   */
00126   bool alloced_buffer;
00127 
00128   io_cache_st() :
00129     pos_in_file(0),
00130     end_of_file(0),
00131     read_pos(0),
00132     read_end(0),
00133     buffer(0),
00134     request_pos(0),
00135     write_buffer(0),
00136     append_read_pos(0),
00137     write_pos(0),
00138     write_end(0),
00139     current_pos(0),
00140     current_end(0),
00141     read_function(0),
00142     write_function(0),
00143     type(TYPE_NOT_SET),
00144     error(0),
00145     pre_read(0),
00146     post_read(0),
00147     pre_close(0),
00148     arg(0),
00149     file_name(0),
00150     dir(0),
00151     prefix(0),
00152     file(0),
00153     seek_not_done(0),
00154     buffer_length(0),
00155     read_length(0),
00156     myflags(0),
00157     alloced_buffer(0)
00158   { }
00159 
00160   int get();
00161   int block_write(const void*, size_t, my_off_t);
00162   void close_cached_file();
00163   bool real_open_cached_file();
00164   int end_io_cache();
00165   int init_io_cache(int file, size_t cachesize, cache_type type, my_off_t seek_offset, bool use_async_io, myf cache_myflags);
00166   void init_functions();
00167 
00168   bool reinit_io_cache(cache_type type_arg, my_off_t seek_offset, bool use_async_io, bool clear_cache);
00169   void setup_io_cache();
00170   bool open_cached_file(const char *dir, const char *prefix, size_t cache_size, myf cache_myflags);
00171   int flush(int need_append_buffer_lock= 1);
00172 
00173   void clear()
00174   {
00175     buffer= NULL;
00176   }
00177 
00178   bool inited() const
00179   {
00180     return buffer;
00181   }
00182 
00183   my_off_t tell() const
00184   {
00185     return pos_in_file + *current_pos - request_pos;
00186   }
00187 
00188   int read(void* Buffer0, size_t Count)
00189   {
00190     unsigned char* Buffer= reinterpret_cast<unsigned char*>(Buffer0);
00191     if (read_pos + Count > read_end)
00192       return read_function(this, Buffer, Count);
00193     memcpy(Buffer, read_pos, Count);
00194     read_pos += Count;
00195     return 0;
00196   }
00197 
00198   int write(const void* Buffer0, size_t Count)
00199   {
00200     const unsigned char* Buffer= reinterpret_cast<const unsigned char*>(Buffer0);
00201     if (write_pos + Count > write_end)
00202       return write_function(this, Buffer, Count);
00203     memcpy(write_pos, Buffer, Count);
00204     write_pos += Count;
00205     return 0;
00206   }
00207 };
00208 
00209 } /* namespace internal */
00210 } /* namespace drizzled */