1
by brian
clean slate |
1 |
/* Copyright (C) 2000 MySQL AB
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
1802.10.2
by Monty Taylor
Update all of the copyright headers to include the correct address. |
14 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
1
by brian
clean slate |
15 |
|
16 |
/*
|
|
17 |
Cashing of files with only does (sequential) read or writes of fixed-
|
|
18 |
length records. A read isn't allowed to go over file-length. A read is ok
|
|
19 |
if it ends at file-length and next read can try to read after file-length
|
|
20 |
(and get a EOF-error).
|
|
21 |
Possibly use of asyncronic io.
|
|
22 |
macros for read and writes for faster io.
|
|
23 |
Used instead of FILE when reading or writing whole files.
|
|
24 |
This code makes mf_rec_cache obsolete (currently only used by ISAM)
|
|
25 |
One can change info->pos_in_file to a higher value to skip bytes in file if
|
|
26 |
also info->read_pos is set to info->read_end.
|
|
27 |
If called through open_cached_file(), then the temporary file will
|
|
28 |
only be created if a write exeeds the file buffer or if one calls
|
|
29 |
my_b_flush_io_cache().
|
|
30 |
||
31 |
If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
|
|
32 |
reading and another for writing. Reads are first done from disk and
|
|
33 |
then done from the write buffer. This is an efficient way to read
|
|
34 |
from a log file when one is writing to it at the same time.
|
|
35 |
For this to work, the file has to be opened in append mode!
|
|
36 |
Note that when one uses SEQ_READ_APPEND, one MUST write using
|
|
37 |
my_b_append ! This is needed because we need to lock the mutex
|
|
38 |
every time we access the write buffer.
|
|
39 |
||
40 |
TODO:
|
|
41 |
When one SEQ_READ_APPEND and we are reading and writing at the same time,
|
|
42 |
each time the write buffer gets full and it's written to disk, we will
|
|
43 |
always do a disk read to read a part of the buffer from disk to the
|
|
44 |
read buffer.
|
|
45 |
This should be fixed so that when we do a my_b_flush_io_cache() and
|
|
46 |
we have been reading the write buffer, we should transfer the rest of the
|
|
47 |
write buffer to the read buffer before we start to reuse it.
|
|
48 |
*/
|
|
49 |
||
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
50 |
#include <config.h> |
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
51 |
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
52 |
#include <drizzled/internal/my_sys.h> |
53 |
#include <drizzled/internal/m_string.h> |
|
54 |
#include <drizzled/drizzled.h> |
|
1
by brian
clean slate |
55 |
#ifdef HAVE_AIOWAIT
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
56 |
#include <drizzled/error.h> |
57 |
#include <drizzled/internal/aio_result.h> |
|
1
by brian
clean slate |
58 |
static void my_aiowait(my_aio_result *result); |
59 |
#endif
|
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
60 |
#include <drizzled/internal/iocache.h> |
1
by brian
clean slate |
61 |
#include <errno.h> |
492.1.7
by Monty Taylor
Moved test() to its own file. |
62 |
#include <drizzled/util/test.h> |
629.1.1
by Monty Taylor
More solaris fixes. |
63 |
#include <stdlib.h> |
1067.4.10
by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max. |
64 |
#include <algorithm> |
65 |
||
66 |
using namespace std; |
|
629.1.1
by Monty Taylor
More solaris fixes. |
67 |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
68 |
namespace drizzled |
69 |
{
|
|
70 |
namespace internal |
|
71 |
{
|
|
72 |
||
2187.4.1
by Olaf van der Spek
Remove register keyword |
73 |
static int _my_b_read(st_io_cache *info, unsigned char *Buffer, size_t Count); |
74 |
static int _my_b_write(st_io_cache *info, const unsigned char *Buffer, size_t Count); |
|
1165.1.147
by Stewart Smith
make _my_b_read() static to mysys/mf_iocache.cc |
75 |
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
76 |
/**
|
77 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
78 |
* Lock appends for the st_io_cache if required (need_append_buffer_lock)
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
79 |
*/
|
80 |
inline
|
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
81 |
static void lock_append_buffer(st_io_cache *, int ) |
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
82 |
{
|
83 |
}
|
|
84 |
||
85 |
/**
|
|
86 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
87 |
* Unlock appends for the st_io_cache if required (need_append_buffer_lock)
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
88 |
*/
|
89 |
inline
|
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
90 |
static void unlock_append_buffer(st_io_cache *, int ) |
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
91 |
{
|
92 |
}
|
|
93 |
||
94 |
/**
|
|
95 |
* @brief
|
|
96 |
* Round up to the nearest IO_SIZE boundary
|
|
97 |
*/
|
|
98 |
inline
|
|
99 |
static size_t io_round_up(size_t x) |
|
100 |
{
|
|
101 |
return ((x+IO_SIZE-1) & ~(IO_SIZE-1)); |
|
102 |
}
|
|
103 |
||
104 |
/**
|
|
105 |
* @brief
|
|
106 |
* Round down to the nearest IO_SIZE boundary
|
|
107 |
*/
|
|
108 |
inline
|
|
109 |
static size_t io_round_dn(size_t x) |
|
110 |
{
|
|
111 |
return (x & ~(IO_SIZE-1)); |
|
112 |
}
|
|
113 |
||
114 |
||
115 |
/**
|
|
116 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
117 |
* Setup internal pointers inside st_io_cache
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
118 |
*
|
119 |
* @details
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
120 |
* This is called on automatically on init or reinit of st_io_cache
|
121 |
* It must be called externally if one moves or copies an st_io_cache object.
|
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
122 |
*
|
123 |
* @param info Cache handler to setup
|
|
124 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
125 |
void st_io_cache::setup_io_cache() |
1
by brian
clean slate |
126 |
{
|
127 |
/* Ensure that my_b_tell() and my_b_bytes_in_cache works */
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
128 |
if (type == WRITE_CACHE) |
1
by brian
clean slate |
129 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
130 |
current_pos= &write_pos; |
131 |
current_end= &write_end; |
|
1
by brian
clean slate |
132 |
}
|
133 |
else
|
|
134 |
{
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
135 |
current_pos= &read_pos; |
136 |
current_end= &read_end; |
|
1
by brian
clean slate |
137 |
}
|
138 |
}
|
|
139 |
||
140 |
||
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
141 |
void st_io_cache::init_functions() |
1
by brian
clean slate |
142 |
{
|
143 |
switch (type) { |
|
144 |
case READ_NET: |
|
145 |
/*
|
|
146 |
Must be initialized by the caller. The problem is that
|
|
147 |
_my_b_net_read has to be defined in sql directory because of
|
|
148 |
the dependency on THD, and therefore cannot be visible to
|
|
149 |
programs that link against mysys but know nothing about THD, such
|
|
150 |
as myisamchk
|
|
151 |
*/
|
|
152 |
break; |
|
153 |
default: |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
154 |
read_function = _my_b_read; |
155 |
write_function = _my_b_write; |
|
1
by brian
clean slate |
156 |
}
|
157 |
||
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
158 |
setup_io_cache(); |
1
by brian
clean slate |
159 |
}
|
160 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
161 |
/**
|
162 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
163 |
* Initialize an st_io_cache object
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
164 |
*
|
165 |
* @param file File that should be associated with the handler
|
|
166 |
* If == -1 then real_open_cached_file() will be called when it's time to open file.
|
|
167 |
* @param cachesize Size of buffer to allocate for read/write
|
|
168 |
* If == 0 then use my_default_record_cache_size
|
|
169 |
* @param type Type of cache
|
|
170 |
* @param seek_offset Where cache should start reading/writing
|
|
171 |
* @param use_async_io Set to 1 if we should use async_io (if avaiable)
|
|
172 |
* @param cache_myflags Bitmap of different flags
|
|
173 |
MY_WME | MY_FAE | MY_NABP | MY_FNABP | MY_DONT_CHECK_FILESIZE
|
|
174 |
*
|
|
175 |
* @retval 0 success
|
|
176 |
* @retval # error
|
|
177 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
178 |
int st_io_cache::init_io_cache(int file_arg, size_t cachesize, |
179 |
enum cache_type type_arg, my_off_t seek_offset, |
|
180 |
bool use_async_io, myf cache_myflags) |
|
1
by brian
clean slate |
181 |
{
|
182 |
size_t min_cache; |
|
656.1.39
by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek. |
183 |
off_t pos; |
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
184 |
my_off_t end_of_file_local= ~(my_off_t) 0; |
1
by brian
clean slate |
185 |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
186 |
file= file_arg; |
187 |
type= TYPE_NOT_SET; /* Don't set it until mutex are created */ |
|
188 |
pos_in_file= seek_offset; |
|
189 |
pre_close = pre_read = post_read = 0; |
|
190 |
arg = 0; |
|
191 |
alloced_buffer = 0; |
|
192 |
buffer=0; |
|
193 |
seek_not_done= 0; |
|
1
by brian
clean slate |
194 |
|
195 |
if (file >= 0) |
|
196 |
{
|
|
656.1.39
by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek. |
197 |
pos= lseek(file, 0, SEEK_CUR); |
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
198 |
if ((pos == MY_FILEPOS_ERROR) && (errno == ESPIPE)) |
1
by brian
clean slate |
199 |
{
|
200 |
/*
|
|
201 |
This kind of object doesn't support seek() or tell(). Don't set a
|
|
202 |
flag that will make us again try to seek() later and fail.
|
|
203 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
204 |
seek_not_done= 0; |
1
by brian
clean slate |
205 |
/*
|
206 |
Additionally, if we're supposed to start somewhere other than the
|
|
207 |
the beginning of whatever this file is, then somebody made a bad
|
|
208 |
assumption.
|
|
209 |
*/
|
|
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
210 |
assert(seek_offset == 0); |
1
by brian
clean slate |
211 |
}
|
212 |
else
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
213 |
seek_not_done= test(seek_offset != (my_off_t)pos); |
1
by brian
clean slate |
214 |
}
|
215 |
||
216 |
if (!cachesize && !(cachesize= my_default_record_cache_size)) |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
217 |
return 1; /* No cache requested */ |
1
by brian
clean slate |
218 |
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2; |
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
219 |
if (type_arg == READ_CACHE) |
1
by brian
clean slate |
220 |
{ /* Assume file isn't growing */ |
221 |
if (!(cache_myflags & MY_DONT_CHECK_FILESIZE)) |
|
222 |
{
|
|
223 |
/* Calculate end of file to avoid allocating oversized buffers */
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
224 |
end_of_file_local=lseek(file,0L,SEEK_END); |
1
by brian
clean slate |
225 |
/* Need to reset seek_not_done now that we just did a seek. */
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
226 |
seek_not_done= end_of_file_local == seek_offset ? 0 : 1; |
227 |
if (end_of_file_local < seek_offset) |
|
228 |
end_of_file_local=seek_offset; |
|
1
by brian
clean slate |
229 |
/* Trim cache size if the file is very small */
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
230 |
if ((my_off_t) cachesize > end_of_file_local-seek_offset+IO_SIZE*2-1) |
1
by brian
clean slate |
231 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
232 |
cachesize= (size_t) (end_of_file_local-seek_offset)+IO_SIZE*2-1; |
1
by brian
clean slate |
233 |
use_async_io=0; /* No need to use async */ |
234 |
}
|
|
235 |
}
|
|
236 |
}
|
|
237 |
cache_myflags &= ~MY_DONT_CHECK_FILESIZE; |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
238 |
if (type_arg != READ_NET && type_arg != WRITE_NET) |
1
by brian
clean slate |
239 |
{
|
240 |
/* Retry allocating memory in smaller blocks until we get one */
|
|
241 |
cachesize= ((cachesize + min_cache-1) & ~(min_cache-1)); |
|
242 |
for (;;) |
|
243 |
{
|
|
244 |
size_t buffer_block; |
|
245 |
if (cachesize < min_cache) |
|
246 |
cachesize = min_cache; |
|
247 |
buffer_block= cachesize; |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
248 |
if ((type_arg == READ_CACHE) and (not global_read_buffer.add(buffer_block))) |
1796.4.11
by Andrew Hutchings
Add global constraint on read buffer |
249 |
{
|
250 |
my_error(ER_OUT_OF_GLOBAL_READMEMORY, MYF(ME_ERROR+ME_WAITTANG)); |
|
251 |
return 2; |
|
252 |
}
|
|
253 |
||
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
254 |
if ((buffer= |
656.1.26
by Monty Taylor
Finally removed all of the my_malloc stuff. |
255 |
(unsigned char*) malloc(buffer_block)) != 0) |
1
by brian
clean slate |
256 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
257 |
write_buffer=buffer; |
258 |
alloced_buffer= true; |
|
1
by brian
clean slate |
259 |
break; /* Enough memory found */ |
260 |
}
|
|
261 |
if (cachesize == min_cache) |
|
1796.4.11
by Andrew Hutchings
Add global constraint on read buffer |
262 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
263 |
if (type_arg == READ_CACHE) |
1796.4.11
by Andrew Hutchings
Add global constraint on read buffer |
264 |
global_read_buffer.sub(buffer_block); |
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
265 |
return 2; /* Can't alloc cache */ |
1796.4.11
by Andrew Hutchings
Add global constraint on read buffer |
266 |
}
|
1
by brian
clean slate |
267 |
/* Try with less memory */
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
268 |
if (type_arg == READ_CACHE) |
1796.4.11
by Andrew Hutchings
Add global constraint on read buffer |
269 |
global_read_buffer.sub(buffer_block); |
1
by brian
clean slate |
270 |
cachesize= (cachesize*3/4 & ~(min_cache-1)); |
271 |
}
|
|
272 |
}
|
|
273 |
||
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
274 |
read_length=buffer_length=cachesize; |
275 |
myflags=cache_myflags & ~(MY_NABP | MY_FNABP); |
|
276 |
request_pos= read_pos= write_pos = buffer; |
|
1
by brian
clean slate |
277 |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
278 |
if (type_arg == WRITE_CACHE) |
279 |
write_end= |
|
280 |
buffer+buffer_length- (seek_offset & (IO_SIZE-1)); |
|
1
by brian
clean slate |
281 |
else
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
282 |
read_end=buffer; /* Nothing in cache */ |
1
by brian
clean slate |
283 |
|
284 |
/* End_of_file may be changed by user later */
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
285 |
end_of_file= end_of_file_local; |
286 |
error= 0; |
|
287 |
type= type_arg; |
|
288 |
init_functions(); |
|
1
by brian
clean slate |
289 |
#ifdef HAVE_AIOWAIT
|
290 |
if (use_async_io && ! my_disable_async_io) |
|
291 |
{
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
292 |
read_length/=2; |
293 |
read_function=_my_b_async_read; |
|
1
by brian
clean slate |
294 |
}
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
295 |
inited= aio_result.pending= 0; |
1
by brian
clean slate |
296 |
#endif
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
297 |
return 0; |
1
by brian
clean slate |
298 |
} /* init_io_cache */ |
299 |
||
300 |
/* Wait until current request is ready */
|
|
301 |
||
302 |
#ifdef HAVE_AIOWAIT
|
|
303 |
static void my_aiowait(my_aio_result *result) |
|
304 |
{
|
|
305 |
if (result->pending) |
|
306 |
{
|
|
307 |
struct aio_result_t *tmp; |
|
308 |
for (;;) |
|
309 |
{
|
|
310 |
if ((int) (tmp=aiowait((struct timeval *) 0)) == -1) |
|
311 |
{
|
|
312 |
if (errno == EINTR) |
|
313 |
continue; |
|
314 |
result->pending=0; /* Assume everythings is ok */ |
|
315 |
break; |
|
316 |
}
|
|
317 |
((my_aio_result*) tmp)->pending=0; |
|
318 |
if ((my_aio_result*) tmp == result) |
|
319 |
break; |
|
320 |
}
|
|
321 |
}
|
|
322 |
}
|
|
323 |
#endif
|
|
324 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
325 |
/**
|
326 |
* @brief
|
|
327 |
* Reset the cache
|
|
328 |
*
|
|
329 |
* @detail
|
|
330 |
* Use this to reset cache to re-start reading or to change the type
|
|
331 |
* between READ_CACHE <-> WRITE_CACHE
|
|
332 |
* If we are doing a reinit of a cache where we have the start of the file
|
|
333 |
* in the cache, we are reusing this memory without flushing it to disk.
|
|
334 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
335 |
bool st_io_cache::reinit_io_cache(enum cache_type type_arg, |
336 |
my_off_t seek_offset, |
|
337 |
bool use_async_io, |
|
338 |
bool clear_cache) |
|
1
by brian
clean slate |
339 |
{
|
340 |
/* One can't do reinit with the following types */
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
341 |
assert(type_arg != READ_NET && type != READ_NET && |
342 |
type_arg != WRITE_NET && type != WRITE_NET); |
|
1
by brian
clean slate |
343 |
|
344 |
/* If the whole file is in memory, avoid flushing to disk */
|
|
345 |
if (! clear_cache && |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
346 |
seek_offset >= pos_in_file && |
347 |
seek_offset <= my_b_tell(this)) |
|
1
by brian
clean slate |
348 |
{
|
349 |
/* Reuse current buffer without flushing it to disk */
|
|
481
by Brian Aker
Remove all of uchar. |
350 |
unsigned char *pos; |
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
351 |
if (type == WRITE_CACHE && type_arg == READ_CACHE) |
1
by brian
clean slate |
352 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
353 |
read_end=write_pos; |
354 |
end_of_file=my_b_tell(this); |
|
1
by brian
clean slate |
355 |
/*
|
356 |
Trigger a new seek only if we have a valid
|
|
357 |
file handle.
|
|
358 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
359 |
seek_not_done= (file != -1); |
1
by brian
clean slate |
360 |
}
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
361 |
else if (type_arg == WRITE_CACHE) |
1
by brian
clean slate |
362 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
363 |
if (type == READ_CACHE) |
1
by brian
clean slate |
364 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
365 |
write_end=write_buffer+buffer_length; |
366 |
seek_not_done=1; |
|
1
by brian
clean slate |
367 |
}
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
368 |
end_of_file = ~(my_off_t) 0; |
1
by brian
clean slate |
369 |
}
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
370 |
pos=request_pos+(seek_offset-pos_in_file); |
371 |
if (type_arg == WRITE_CACHE) |
|
372 |
write_pos=pos; |
|
1
by brian
clean slate |
373 |
else
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
374 |
read_pos= pos; |
1
by brian
clean slate |
375 |
#ifdef HAVE_AIOWAIT
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
376 |
my_aiowait(&aio_result); /* Wait for outstanding req */ |
1
by brian
clean slate |
377 |
#endif
|
378 |
}
|
|
379 |
else
|
|
380 |
{
|
|
381 |
/*
|
|
382 |
If we change from WRITE_CACHE to READ_CACHE, assume that everything
|
|
383 |
after the current positions should be ignored
|
|
384 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
385 |
if (type == WRITE_CACHE && type_arg == READ_CACHE) |
386 |
end_of_file=my_b_tell(this); |
|
1
by brian
clean slate |
387 |
/* flush cache if we want to reuse it */
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
388 |
if (!clear_cache && my_b_flush_io_cache(this, 1)) |
389 |
return 1; |
|
390 |
pos_in_file=seek_offset; |
|
1
by brian
clean slate |
391 |
/* Better to do always do a seek */
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
392 |
seek_not_done=1; |
393 |
request_pos=read_pos=write_pos=buffer; |
|
394 |
if (type_arg == READ_CACHE) |
|
1
by brian
clean slate |
395 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
396 |
read_end=buffer; /* Nothing in cache */ |
1
by brian
clean slate |
397 |
}
|
398 |
else
|
|
399 |
{
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
400 |
write_end=(buffer + buffer_length - |
1
by brian
clean slate |
401 |
(seek_offset & (IO_SIZE-1))); |
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
402 |
end_of_file= ~(my_off_t) 0; |
1
by brian
clean slate |
403 |
}
|
404 |
}
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
405 |
type= type_arg; |
406 |
error=0; |
|
407 |
init_functions(); |
|
1
by brian
clean slate |
408 |
|
409 |
#ifdef HAVE_AIOWAIT
|
|
410 |
if (use_async_io && ! my_disable_async_io && |
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
411 |
((uint32_t) buffer_length < |
412 |
(uint32_t) (end_of_file - seek_offset))) |
|
1
by brian
clean slate |
413 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
414 |
read_length=buffer_length/2; |
415 |
read_function=_my_b_async_read; |
|
1
by brian
clean slate |
416 |
}
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
417 |
inited= 0; |
595
by Brian Aker
Fix, partial, for Sun Studio. |
418 |
#else
|
419 |
(void)use_async_io; |
|
1
by brian
clean slate |
420 |
#endif
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
421 |
return 0; |
1
by brian
clean slate |
422 |
} /* reinit_io_cache */ |
423 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
424 |
/**
|
425 |
* @brief
|
|
426 |
* Read buffered.
|
|
427 |
*
|
|
428 |
* @detail
|
|
429 |
* This function is only called from the my_b_read() macro when there
|
|
430 |
* aren't enough characters in the buffer to satisfy the request.
|
|
431 |
*
|
|
432 |
* WARNING
|
|
433 |
* When changing this function, be careful with handling file offsets
|
|
434 |
* (end-of_file, pos_in_file). Do not cast them to possibly smaller
|
|
435 |
* types than my_off_t unless you can be sure that their value fits.
|
|
436 |
* Same applies to differences of file offsets.
|
|
437 |
*
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
438 |
* @param info st_io_cache pointer @param Buffer Buffer to retrieve count bytes
|
1578.4.3
by Brian Aker
Remove dead code in IO_CACHE for shared access. |
439 |
* from file @param Count Number of bytes to read into Buffer
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
440 |
*
|
441 |
* @retval 0 We succeeded in reading all data
|
|
442 |
* @retval 1 Error: can't read requested characters
|
|
443 |
*/
|
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
444 |
static int _my_b_read(st_io_cache *info, unsigned char *Buffer, size_t Count) |
1
by brian
clean slate |
445 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
446 |
size_t length_local,diff_length,left_length, max_length; |
447 |
my_off_t pos_in_file_local; |
|
1
by brian
clean slate |
448 |
|
449 |
if ((left_length= (size_t) (info->read_end-info->read_pos))) |
|
450 |
{
|
|
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
451 |
assert(Count >= left_length); /* User is not using my_b_read() */ |
1
by brian
clean slate |
452 |
memcpy(Buffer,info->read_pos, left_length); |
453 |
Buffer+=left_length; |
|
454 |
Count-=left_length; |
|
455 |
}
|
|
456 |
||
457 |
/* pos_in_file always point on where info->buffer was read */
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
458 |
pos_in_file_local=info->pos_in_file+ (size_t) (info->read_end - info->buffer); |
1
by brian
clean slate |
459 |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
460 |
/*
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
461 |
Whenever a function which operates on st_io_cache flushes/writes
|
462 |
some part of the st_io_cache to disk it will set the property
|
|
1
by brian
clean slate |
463 |
"seek_not_done" to indicate this to other functions operating
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
464 |
on the st_io_cache.
|
1
by brian
clean slate |
465 |
*/
|
466 |
if (info->seek_not_done) |
|
467 |
{
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
468 |
if ((lseek(info->file,pos_in_file_local,SEEK_SET) != MY_FILEPOS_ERROR)) |
1
by brian
clean slate |
469 |
{
|
470 |
/* No error, reset seek_not_done flag. */
|
|
471 |
info->seek_not_done= 0; |
|
472 |
}
|
|
473 |
else
|
|
474 |
{
|
|
475 |
/*
|
|
476 |
If the seek failed and the error number is ESPIPE, it is because
|
|
477 |
info->file is a pipe or socket or FIFO. We never should have tried
|
|
478 |
to seek on that. See Bugs#25807 and #22828 for more info.
|
|
479 |
*/
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
480 |
assert(errno != ESPIPE); |
1
by brian
clean slate |
481 |
info->error= -1; |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
482 |
return(1); |
1
by brian
clean slate |
483 |
}
|
484 |
}
|
|
485 |
||
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
486 |
diff_length= (size_t) (pos_in_file_local & (IO_SIZE-1)); |
1
by brian
clean slate |
487 |
if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length))) |
488 |
{ /* Fill first intern buffer */ |
|
489 |
size_t read_length; |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
490 |
if (info->end_of_file <= pos_in_file_local) |
1
by brian
clean slate |
491 |
{ /* End of file */ |
492 |
info->error= (int) left_length; |
|
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
493 |
return(1); |
1
by brian
clean slate |
494 |
}
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
495 |
length_local=(Count & (size_t) ~(IO_SIZE-1))-diff_length; |
496 |
if ((read_length= my_read(info->file,Buffer, length_local, info->myflags)) != length_local) |
|
1
by brian
clean slate |
497 |
{
|
498 |
info->error= (read_length == (size_t) -1 ? -1 : |
|
499 |
(int) (read_length+left_length)); |
|
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
500 |
return(1); |
1
by brian
clean slate |
501 |
}
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
502 |
Count-= length_local; |
503 |
Buffer+= length_local; |
|
504 |
pos_in_file_local+= length_local; |
|
505 |
left_length+= length_local; |
|
1
by brian
clean slate |
506 |
diff_length=0; |
507 |
}
|
|
508 |
||
509 |
max_length= info->read_length-diff_length; |
|
510 |
if (info->type != READ_FIFO && |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
511 |
max_length > (info->end_of_file - pos_in_file_local)) |
512 |
max_length= (size_t) (info->end_of_file - pos_in_file_local); |
|
1
by brian
clean slate |
513 |
if (!max_length) |
514 |
{
|
|
515 |
if (Count) |
|
516 |
{
|
|
1126.13.8
by Joe Daly
Fix up spacing in various files, also had new style casts in several places |
517 |
info->error= static_cast<int>(left_length); /* We only got this many char */ |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
518 |
return(1); |
1
by brian
clean slate |
519 |
}
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
520 |
length_local=0; /* Didn't read any chars */ |
1
by brian
clean slate |
521 |
}
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
522 |
else if (( length_local= my_read(info->file,info->buffer, max_length, |
1
by brian
clean slate |
523 |
info->myflags)) < Count || |
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
524 |
length_local == (size_t) -1) |
1
by brian
clean slate |
525 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
526 |
if ( length_local != (size_t) -1) |
527 |
memcpy(Buffer, info->buffer, length_local); |
|
528 |
info->pos_in_file= pos_in_file_local; |
|
529 |
info->error= length_local == (size_t) -1 ? -1 : (int) ( length_local+left_length); |
|
1
by brian
clean slate |
530 |
info->read_pos=info->read_end=info->buffer; |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
531 |
return(1); |
1
by brian
clean slate |
532 |
}
|
533 |
info->read_pos=info->buffer+Count; |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
534 |
info->read_end=info->buffer+ length_local; |
535 |
info->pos_in_file=pos_in_file_local; |
|
1
by brian
clean slate |
536 |
memcpy(Buffer, info->buffer, Count); |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
537 |
return(0); |
1
by brian
clean slate |
538 |
}
|
539 |
||
540 |
||
541 |
#ifdef HAVE_AIOWAIT
|
|
542 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
543 |
/**
|
544 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
545 |
* Read from the st_io_cache into a buffer and feed asynchronously from disk when needed.
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
546 |
*
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
547 |
* @param info st_io_cache pointer
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
548 |
* @param Buffer Buffer to retrieve count bytes from file
|
549 |
* @param Count Number of bytes to read into Buffer
|
|
550 |
*
|
|
551 |
* @retval -1 An error has occurred; errno is set.
|
|
552 |
* @retval 0 Success
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
553 |
* @retval 1 An error has occurred; st_io_cache to error state.
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
554 |
*/
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
555 |
int _my_b_async_read(st_io_cache *info, unsigned char *Buffer, size_t Count) |
1
by brian
clean slate |
556 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
557 |
size_t length_local,read_length,diff_length,left_length,use_length,org_Count; |
1
by brian
clean slate |
558 |
size_t max_length; |
1241.13.1
by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys. |
559 |
my_off_t next_pos_in_file; |
481
by Brian Aker
Remove all of uchar. |
560 |
unsigned char *read_buffer; |
1
by brian
clean slate |
561 |
|
562 |
memcpy(Buffer,info->read_pos, |
|
563 |
(left_length= (size_t) (info->read_end-info->read_pos))); |
|
564 |
Buffer+=left_length; |
|
565 |
org_Count=Count; |
|
566 |
Count-=left_length; |
|
567 |
||
568 |
if (info->inited) |
|
569 |
{ /* wait for read block */ |
|
570 |
info->inited=0; /* No more block to read */ |
|
571 |
my_aiowait(&info->aio_result); /* Wait for outstanding req */ |
|
572 |
if (info->aio_result.result.aio_errno) |
|
573 |
{
|
|
574 |
if (info->myflags & MY_WME) |
|
575 |
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), |
|
576 |
my_filename(info->file), |
|
577 |
info->aio_result.result.aio_errno); |
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
578 |
errno=info->aio_result.result.aio_errno; |
1
by brian
clean slate |
579 |
info->error= -1; |
580 |
return(1); |
|
581 |
}
|
|
582 |
if (! (read_length= (size_t) info->aio_result.result.aio_return) || |
|
583 |
read_length == (size_t) -1) |
|
584 |
{
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
585 |
errno=0; /* For testing */ |
1
by brian
clean slate |
586 |
info->error= (read_length == (size_t) -1 ? -1 : |
587 |
(int) (read_length+left_length)); |
|
588 |
return(1); |
|
589 |
}
|
|
590 |
info->pos_in_file+= (size_t) (info->read_end - info->request_pos); |
|
591 |
||
592 |
if (info->request_pos != info->buffer) |
|
593 |
info->request_pos=info->buffer; |
|
594 |
else
|
|
595 |
info->request_pos=info->buffer+info->read_length; |
|
596 |
info->read_pos=info->request_pos; |
|
597 |
next_pos_in_file=info->aio_read_pos+read_length; |
|
598 |
||
599 |
/* Check if pos_in_file is changed
|
|
600 |
(_ni_read_cache may have skipped some bytes) */
|
|
601 |
||
602 |
if (info->aio_read_pos < info->pos_in_file) |
|
603 |
{ /* Fix if skipped bytes */ |
|
604 |
if (info->aio_read_pos + read_length < info->pos_in_file) |
|
605 |
{
|
|
606 |
read_length=0; /* Skip block */ |
|
607 |
next_pos_in_file=info->pos_in_file; |
|
608 |
}
|
|
609 |
else
|
|
610 |
{
|
|
1241.13.1
by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys. |
611 |
my_off_t offset= (info->pos_in_file - info->aio_read_pos); |
1
by brian
clean slate |
612 |
info->pos_in_file=info->aio_read_pos; /* Whe are here */ |
613 |
info->read_pos=info->request_pos+offset; |
|
614 |
read_length-=offset; /* Bytes left from read_pos */ |
|
615 |
}
|
|
616 |
}
|
|
617 |
/* Copy found bytes to buffer */
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
618 |
length_local=min(Count,read_length); |
619 |
memcpy(Buffer,info->read_pos,(size_t) length_local); |
|
620 |
Buffer+=length_local; |
|
621 |
Count-=length_local; |
|
622 |
left_length+=length_local; |
|
1
by brian
clean slate |
623 |
info->read_end=info->rc_pos+read_length; |
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
624 |
info->read_pos+=length_local; |
1
by brian
clean slate |
625 |
}
|
626 |
else
|
|
627 |
next_pos_in_file=(info->pos_in_file+ (size_t) |
|
628 |
(info->read_end - info->request_pos)); |
|
629 |
||
630 |
/* If reading large blocks, or first read or read with skip */
|
|
631 |
if (Count) |
|
632 |
{
|
|
633 |
if (next_pos_in_file == info->end_of_file) |
|
634 |
{
|
|
635 |
info->error=(int) (read_length+left_length); |
|
636 |
return 1; |
|
637 |
}
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
638 |
|
656.1.39
by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek. |
639 |
if (lseek(info->file,next_pos_in_file,SEEK_SET) == MY_FILEPOS_ERROR) |
1
by brian
clean slate |
640 |
{
|
641 |
info->error= -1; |
|
642 |
return (1); |
|
643 |
}
|
|
644 |
||
645 |
read_length=IO_SIZE*2- (size_t) (next_pos_in_file & (IO_SIZE-1)); |
|
646 |
if (Count < read_length) |
|
647 |
{ /* Small block, read to cache */ |
|
648 |
if ((read_length=my_read(info->file,info->request_pos, |
|
649 |
read_length, info->myflags)) == (size_t) -1) |
|
650 |
return info->error= -1; |
|
1067.4.10
by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max. |
651 |
use_length=min(Count,read_length); |
1
by brian
clean slate |
652 |
memcpy(Buffer,info->request_pos,(size_t) use_length); |
653 |
info->read_pos=info->request_pos+Count; |
|
654 |
info->read_end=info->request_pos+read_length; |
|
655 |
info->pos_in_file=next_pos_in_file; /* Start of block in cache */ |
|
656 |
next_pos_in_file+=read_length; |
|
657 |
||
658 |
if (Count != use_length) |
|
659 |
{ /* Didn't find hole block */ |
|
660 |
if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count) |
|
661 |
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), |
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
662 |
my_filename(info->file),errno); |
1
by brian
clean slate |
663 |
info->error=(int) (read_length+left_length); |
664 |
return 1; |
|
665 |
}
|
|
666 |
}
|
|
667 |
else
|
|
668 |
{ /* Big block, don't cache it */ |
|
669 |
if ((read_length= my_read(info->file,Buffer, Count,info->myflags)) |
|
670 |
!= Count) |
|
671 |
{
|
|
672 |
info->error= read_length == (size_t) -1 ? -1 : read_length+left_length; |
|
673 |
return 1; |
|
674 |
}
|
|
675 |
info->read_pos=info->read_end=info->request_pos; |
|
676 |
info->pos_in_file=(next_pos_in_file+=Count); |
|
677 |
}
|
|
678 |
}
|
|
679 |
||
680 |
/* Read next block with asyncronic io */
|
|
681 |
diff_length=(next_pos_in_file & (IO_SIZE-1)); |
|
682 |
max_length= info->read_length - diff_length; |
|
683 |
if (max_length > info->end_of_file - next_pos_in_file) |
|
684 |
max_length= (size_t) (info->end_of_file - next_pos_in_file); |
|
685 |
||
686 |
if (info->request_pos != info->buffer) |
|
687 |
read_buffer=info->buffer; |
|
688 |
else
|
|
689 |
read_buffer=info->buffer+info->read_length; |
|
690 |
info->aio_read_pos=next_pos_in_file; |
|
691 |
if (max_length) |
|
692 |
{
|
|
693 |
info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */ |
|
694 |
if (aioread(info->file,read_buffer, max_length, |
|
1241.13.1
by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys. |
695 |
(my_off_t) next_pos_in_file,SEEK_SET, |
1
by brian
clean slate |
696 |
&info->aio_result.result)) |
697 |
{ /* Skip async io */ |
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
698 |
errno=errno; |
1
by brian
clean slate |
699 |
if (info->request_pos != info->buffer) |
700 |
{
|
|
629.3.4
by Kristian Nielsen
Take Mats'es changes from bmove()->memcpy(), and fix all of them to be |
701 |
memmove(info->buffer, info->request_pos, |
702 |
(size_t) (info->read_end - info->read_pos)); |
|
1
by brian
clean slate |
703 |
info->request_pos=info->buffer; |
704 |
info->read_pos-=info->read_length; |
|
705 |
info->read_end-=info->read_length; |
|
706 |
}
|
|
707 |
info->read_length=info->buffer_length; /* Use hole buffer */ |
|
708 |
info->read_function=_my_b_read; /* Use normal IO_READ next */ |
|
709 |
}
|
|
710 |
else
|
|
711 |
info->inited=info->aio_result.pending=1; |
|
712 |
}
|
|
713 |
return 0; /* Block read, async in use */ |
|
714 |
} /* _my_b_async_read */ |
|
715 |
#endif
|
|
716 |
||
717 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
718 |
/**
|
719 |
* @brief
|
|
720 |
* Read one byte when buffer is empty
|
|
721 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
722 |
int _my_b_get(st_io_cache *info) |
1
by brian
clean slate |
723 |
{
|
481
by Brian Aker
Remove all of uchar. |
724 |
unsigned char buff; |
1
by brian
clean slate |
725 |
IO_CACHE_CALLBACK pre_read,post_read; |
726 |
if ((pre_read = info->pre_read)) |
|
727 |
(*pre_read)(info); |
|
728 |
if ((*(info)->read_function)(info,&buff,1)) |
|
729 |
return my_b_EOF; |
|
730 |
if ((post_read = info->post_read)) |
|
731 |
(*post_read)(info); |
|
481
by Brian Aker
Remove all of uchar. |
732 |
return (int) (unsigned char) buff; |
1
by brian
clean slate |
733 |
}
|
734 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
735 |
/**
|
736 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
737 |
* Write a byte buffer to st_io_cache and flush to disk if st_io_cache is full.
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
738 |
*
|
739 |
* @retval -1 On error; errno contains error code.
|
|
740 |
* @retval 0 On success
|
|
741 |
* @retval 1 On error on write
|
|
742 |
*/
|
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
743 |
int _my_b_write(st_io_cache *info, const unsigned char *Buffer, size_t Count) |
1
by brian
clean slate |
744 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
745 |
size_t rest_length,length_local; |
1
by brian
clean slate |
746 |
|
747 |
if (info->pos_in_file+info->buffer_length > info->end_of_file) |
|
748 |
{
|
|
1831.1.1
by Andrew Hutchings
Fix new warnings in GCC 4.5 |
749 |
errno=EFBIG; |
1
by brian
clean slate |
750 |
return info->error = -1; |
751 |
}
|
|
752 |
||
753 |
rest_length= (size_t) (info->write_end - info->write_pos); |
|
754 |
memcpy(info->write_pos,Buffer,(size_t) rest_length); |
|
755 |
Buffer+=rest_length; |
|
756 |
Count-=rest_length; |
|
757 |
info->write_pos+=rest_length; |
|
758 |
||
759 |
if (my_b_flush_io_cache(info,1)) |
|
760 |
return 1; |
|
761 |
if (Count >= IO_SIZE) |
|
762 |
{ /* Fill first intern buffer */ |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
763 |
length_local=Count & (size_t) ~(IO_SIZE-1); |
1
by brian
clean slate |
764 |
if (info->seek_not_done) |
765 |
{
|
|
766 |
/*
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
767 |
Whenever a function which operates on st_io_cache flushes/writes
|
768 |
some part of the st_io_cache to disk it will set the property
|
|
1
by brian
clean slate |
769 |
"seek_not_done" to indicate this to other functions operating
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
770 |
on the st_io_cache.
|
1
by brian
clean slate |
771 |
*/
|
656.1.39
by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek. |
772 |
if (lseek(info->file,info->pos_in_file,SEEK_SET)) |
1
by brian
clean slate |
773 |
{
|
774 |
info->error= -1; |
|
775 |
return (1); |
|
776 |
}
|
|
777 |
info->seek_not_done=0; |
|
778 |
}
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
779 |
if (my_write(info->file, Buffer, length_local, info->myflags | MY_NABP)) |
1
by brian
clean slate |
780 |
return info->error= -1; |
781 |
||
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
782 |
Count-=length_local; |
783 |
Buffer+=length_local; |
|
784 |
info->pos_in_file+=length_local; |
|
1
by brian
clean slate |
785 |
}
|
786 |
memcpy(info->write_pos,Buffer,(size_t) Count); |
|
787 |
info->write_pos+=Count; |
|
788 |
return 0; |
|
789 |
}
|
|
790 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
791 |
/**
|
792 |
* @brief
|
|
793 |
* Write a block to disk where part of the data may be inside the record buffer.
|
|
794 |
* As all write calls to the data goes through the cache,
|
|
795 |
* we will never get a seek over the end of the buffer.
|
|
796 |
*/
|
|
2187.4.1
by Olaf van der Spek
Remove register keyword |
797 |
int my_block_write(st_io_cache *info, const unsigned char *Buffer, size_t Count, |
1241.13.1
by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys. |
798 |
my_off_t pos) |
1
by brian
clean slate |
799 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
800 |
size_t length_local; |
1
by brian
clean slate |
801 |
int error=0; |
802 |
||
803 |
if (pos < info->pos_in_file) |
|
804 |
{
|
|
805 |
/* Of no overlap, write everything without buffering */
|
|
806 |
if (pos + Count <= info->pos_in_file) |
|
32
by Brian Aker
More cleanup on pread() |
807 |
return (pwrite(info->file, Buffer, Count, pos) == 0); |
1
by brian
clean slate |
808 |
/* Write the part of the block that is before buffer */
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
809 |
length_local= (uint32_t) (info->pos_in_file - pos); |
810 |
if (pwrite(info->file, Buffer, length_local, pos) == 0) |
|
1
by brian
clean slate |
811 |
info->error= error= -1; |
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
812 |
Buffer+=length_local; |
813 |
pos+= length_local; |
|
814 |
Count-= length_local; |
|
1
by brian
clean slate |
815 |
}
|
816 |
||
817 |
/* Check if we want to write inside the used part of the buffer.*/
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
818 |
length_local= (size_t) (info->write_end - info->buffer); |
819 |
if (pos < info->pos_in_file + length_local) |
|
1
by brian
clean slate |
820 |
{
|
821 |
size_t offset= (size_t) (pos - info->pos_in_file); |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
822 |
length_local-=offset; |
823 |
if (length_local > Count) |
|
824 |
length_local=Count; |
|
825 |
memcpy(info->buffer+offset, Buffer, length_local); |
|
826 |
Buffer+=length_local; |
|
827 |
Count-= length_local; |
|
828 |
/* Fix length_local of buffer if the new data was larger */
|
|
829 |
if (info->buffer+length_local > info->write_pos) |
|
830 |
info->write_pos=info->buffer+length_local; |
|
1
by brian
clean slate |
831 |
if (!Count) |
832 |
return (error); |
|
833 |
}
|
|
834 |
/* Write at the end of the current buffer; This is the normal case */
|
|
835 |
if (_my_b_write(info, Buffer, Count)) |
|
836 |
error= -1; |
|
837 |
return error; |
|
838 |
}
|
|
839 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
840 |
/**
|
841 |
* @brief
|
|
842 |
* Flush write cache
|
|
843 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
844 |
int my_b_flush_io_cache(st_io_cache *info, int need_append_buffer_lock) |
1
by brian
clean slate |
845 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
846 |
size_t length_local; |
1578.4.4
by Brian Aker
Remove pthread mutex that is no longer used (since IO_CACHE is single |
847 |
bool append_cache= false; |
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
848 |
my_off_t pos_in_file_local; |
1
by brian
clean slate |
849 |
|
850 |
if (info->type == WRITE_CACHE || append_cache) |
|
851 |
{
|
|
852 |
if (info->file == -1) |
|
853 |
{
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
854 |
if (info->real_open_cached_file()) |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
855 |
return((info->error= -1)); |
1
by brian
clean slate |
856 |
}
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
857 |
lock_append_buffer(info, need_append_buffer_lock); |
1
by brian
clean slate |
858 |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
859 |
if ((length_local=(size_t) (info->write_pos - info->write_buffer))) |
1
by brian
clean slate |
860 |
{
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
861 |
pos_in_file_local=info->pos_in_file; |
1
by brian
clean slate |
862 |
/*
|
863 |
If we have append cache, we always open the file with
|
|
864 |
O_APPEND which moves the pos to EOF automatically on every write
|
|
865 |
*/
|
|
866 |
if (!append_cache && info->seek_not_done) |
|
867 |
{ /* File touched, do seek */ |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
868 |
if (lseek(info->file,pos_in_file_local,SEEK_SET) == MY_FILEPOS_ERROR) |
1
by brian
clean slate |
869 |
{
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
870 |
unlock_append_buffer(info, need_append_buffer_lock); |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
871 |
return((info->error= -1)); |
1
by brian
clean slate |
872 |
}
|
873 |
if (!append_cache) |
|
874 |
info->seek_not_done=0; |
|
875 |
}
|
|
876 |
if (!append_cache) |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
877 |
info->pos_in_file+=length_local; |
1
by brian
clean slate |
878 |
info->write_end= (info->write_buffer+info->buffer_length- |
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
879 |
((pos_in_file_local+length_local) & (IO_SIZE-1))); |
1
by brian
clean slate |
880 |
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
881 |
if (my_write(info->file,info->write_buffer,length_local, |
1
by brian
clean slate |
882 |
info->myflags | MY_NABP)) |
883 |
info->error= -1; |
|
884 |
else
|
|
885 |
info->error= 0; |
|
886 |
if (!append_cache) |
|
887 |
{
|
|
1909.1.2
by Brian Aker
Additional io_cache encapsulation. |
888 |
set_if_bigger(info->end_of_file,(pos_in_file_local+length_local)); |
1
by brian
clean slate |
889 |
}
|
890 |
else
|
|
891 |
{
|
|
892 |
info->end_of_file+=(info->write_pos-info->append_read_pos); |
|
1241.13.1
by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys. |
893 |
my_off_t tell_ret= lseek(info->file, 0, SEEK_CUR); |
632.1.15
by Monty
Finished fixing my_tell. |
894 |
assert(info->end_of_file == tell_ret); |
1
by brian
clean slate |
895 |
}
|
896 |
||
897 |
info->append_read_pos=info->write_pos=info->write_buffer; |
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
898 |
unlock_append_buffer(info, need_append_buffer_lock); |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
899 |
return(info->error); |
1
by brian
clean slate |
900 |
}
|
901 |
}
|
|
902 |
#ifdef HAVE_AIOWAIT
|
|
903 |
else if (info->type != READ_NET) |
|
904 |
{
|
|
905 |
my_aiowait(&info->aio_result); /* Wait for outstanding req */ |
|
906 |
info->inited=0; |
|
907 |
}
|
|
908 |
#endif
|
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
909 |
unlock_append_buffer(info, need_append_buffer_lock); |
51.3.22
by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile |
910 |
return(0); |
1
by brian
clean slate |
911 |
}
|
912 |
||
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
913 |
/**
|
914 |
* @brief
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
915 |
* Free an st_io_cache object
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
916 |
*
|
917 |
* @detail
|
|
918 |
* It's currently safe to call this if one has called init_io_cache()
|
|
919 |
* on the 'info' object, even if init_io_cache() failed.
|
|
920 |
* This function is also safe to call twice with the same handle.
|
|
921 |
*
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
922 |
* @param info st_io_cache Handle to free
|
1507.1.1
by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen |
923 |
*
|
924 |
* @retval 0 ok
|
|
925 |
* @retval # Error
|
|
926 |
*/
|
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
927 |
int st_io_cache::end_io_cache() |
1
by brian
clean slate |
928 |
{
|
1909.1.1
by Brian Aker
Encapsulation of IO_CACHE. |
929 |
int _error=0; |
930 |
||
931 |
if (pre_close) |
|
932 |
{
|
|
933 |
(*pre_close)(this); |
|
934 |
pre_close= 0; |
|
935 |
}
|
|
936 |
if (alloced_buffer) |
|
937 |
{
|
|
938 |
if (type == READ_CACHE) |
|
939 |
global_read_buffer.sub(buffer_length); |
|
940 |
alloced_buffer=0; |
|
941 |
if (file != -1) /* File doesn't exist */ |
|
942 |
_error= my_b_flush_io_cache(this, 1); |
|
943 |
free((unsigned char*) buffer); |
|
944 |
buffer=read_pos=(unsigned char*) 0; |
|
945 |
}
|
|
946 |
||
947 |
return _error; |
|
1
by brian
clean slate |
948 |
} /* end_io_cache */ |
949 |
||
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
950 |
} /* namespace internal */ |
951 |
} /* namespace drizzled */ |