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 { 00027 namespace internal 00028 { 00029 00030 struct st_io_cache; 00031 typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*); 00032 00033 struct st_io_cache /* Used when cacheing files */ 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)(struct st_io_cache *,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)(struct st_io_cache *,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 enum 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 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 #ifdef HAVE_AIOWAIT 00128 /* 00129 As inidicated by ifdef, this is for async I/O, which is not currently 00130 used (because it's not reliable on all systems) 00131 */ 00132 uint32_t inited; 00133 my_off_t aio_read_pos; 00134 my_aio_result aio_result; 00135 #endif 00136 00137 st_io_cache() : 00138 pos_in_file(0), 00139 end_of_file(0), 00140 read_pos(0), 00141 read_end(0), 00142 buffer(0), 00143 request_pos(0), 00144 write_buffer(0), 00145 append_read_pos(0), 00146 write_pos(0), 00147 write_end(0), 00148 current_pos(0), 00149 current_end(0), 00150 read_function(0), 00151 write_function(0), 00152 type(TYPE_NOT_SET), 00153 error(0), 00154 pre_read(0), 00155 post_read(0), 00156 pre_close(0), 00157 arg(0), 00158 file_name(0), 00159 dir(0), 00160 prefix(0), 00161 file(0), 00162 seek_not_done(0), 00163 buffer_length(0), 00164 read_length(0), 00165 myflags(0), 00166 alloced_buffer(0) 00167 #ifdef HAVE_AIOWAIT 00168 , 00169 inited(0), 00170 aio_read_pos(0), 00171 aio_result(0) 00172 #endif 00173 { } 00174 00175 ~st_io_cache() 00176 { } 00177 00178 void close_cached_file(); 00179 bool real_open_cached_file(); 00180 int end_io_cache(); 00181 int init_io_cache(int file, size_t cachesize, 00182 enum cache_type type, my_off_t seek_offset, 00183 bool use_async_io, myf cache_myflags); 00184 void init_functions(); 00185 00186 bool reinit_io_cache(enum cache_type type_arg, 00187 my_off_t seek_offset, 00188 bool use_async_io, 00189 bool clear_cache); 00190 void setup_io_cache(); 00191 bool open_cached_file(const char *dir, 00192 const char *prefix, size_t cache_size, 00193 myf cache_myflags); 00194 00195 }; 00196 00197 typedef struct st_io_cache IO_CACHE; /* Used when cacheing files */ 00198 00199 extern int _my_b_get(st_io_cache *info); 00200 extern int _my_b_async_read(st_io_cache *info,unsigned char *Buffer,size_t Count); 00201 00202 extern int my_block_write(st_io_cache *info, const unsigned char *Buffer, 00203 size_t Count, my_off_t pos); 00204 extern int my_b_flush_io_cache(st_io_cache *info, int need_append_buffer_lock); 00205 00206 #define flush_io_cache(info) my_b_flush_io_cache((info),1) 00207 00208 } /* namespace internal */ 00209 } /* namespace drizzled */ 00210