summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-05-18 11:54:55 +0200
committerSergei Golubchik <serg@mariadb.org>2015-06-02 18:53:37 +0200
commit196e8529837558a72baf31d012285cc283b8e95d (patch)
tree75feb69d20c5fb5944dd6195bf00440143497232 /mysys
parent1841557e407038e3611b0788eaf70fd3d8eb043e (diff)
downloadmariadb-git-196e8529837558a72baf31d012285cc283b8e95d.tar.gz
misc IO_CACHE cleanups
* remove unused (and not implemented) WRITE_NET type * remove cast in my_b_write() macro. my_b_* macros are function-like, casts are responsibility of the caller * replace hackish _my_b_write(info,0,0) with the explicit my_b_flush_io_cache() in my_b_write_byte() * remove unused my_b_fill_cache() * replace pbool -> my_bool * make internal IO_CACHE functions static * reformat comments, correct typos, remove obsolete comments (ISAM) * assert valid cache type in init_functions() * use IO_ROUND_DN() macro where appropriate * remove unused DBUG_EXECUTE_IF in _my_b_cache_write() * remove unnecessary __attribute__((unused)) * fix goto error in parse_file.cc * remove redundant reinit_io_cache() in uniques.cc * don't do reinit_io_cache() if the cache was not initialized in ma_check.c * extract duplicate functionality from various _my_b_*_read functions into a common wrapper. Same for _my_b_*_write * create _my_b_cache_write_r instead of having if's in _my_b_cache_write (similar to existing _my_b_cache_read and _my_b_cache_read_r) * don't call mysql_file_write() from my_b_flush_io_cache(), call info->write_function() instead
Diffstat (limited to 'mysys')
-rw-r--r--mysys/mf_cache.c32
-rw-r--r--mysys/mf_iocache.c352
2 files changed, 199 insertions, 185 deletions
diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c
index 299e4e5f478..a3426889a82 100644
--- a/mysys/mf_cache.c
+++ b/mysys/mf_cache.c
@@ -20,11 +20,12 @@
#include "my_static.h"
#include "mysys_err.h"
- /*
- Remove an open tempfile so that it doesn't survive
- if we crash; If the operating system doesn't support
- this, just remember the file name for later removal
- */
+/**
+ Remove an open tempfile so that it doesn't survive if we crash
+
+ If the operating system doesn't support this, just remember
+ the file name for later removal
+*/
static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
const char *name)
@@ -49,14 +50,14 @@ static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
return 0;
}
- /*
- ** Open tempfile cached by IO_CACHE
- ** Should be used when no seeks are done (only reinit_io_buff)
- ** Return 0 if cache is inited ok
- ** The actual file is created when the IO_CACHE buffer gets filled
- ** If dir is not given, use TMPDIR.
- */
+/**
+ Open tempfile cached by IO_CACHE
+ Should be used when no seeks are done (only reinit_io_buff)
+ Return 0 if cache is inited ok
+ The actual file is created when the IO_CACHE buffer gets filled
+ If dir is not given, use TMPDIR.
+*/
my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
size_t cache_size, myf cache_myflags)
{
@@ -71,7 +72,7 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
cache->prefix[0]= 0;
cache->file_name=0;
cache->buffer=0; /* Mark that not open */
- if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
+ if (!init_io_cache(cache, -1, cache_size, WRITE_CACHE, 0L, 0,
MYF(cache_myflags | MY_NABP)))
{
DBUG_RETURN(0);
@@ -79,8 +80,9 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
DBUG_RETURN(1);
}
- /* Create the temporary file */
-
+/**
+ Create the temporary file
+*/
my_bool real_open_cached_file(IO_CACHE *cache)
{
char name_buff[FN_REFLEN];
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 354995c644d..9160f607448 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -23,7 +23,6 @@
Possibly use of asyncronic io.
macros for read and writes for faster io.
Used instead of FILE when reading or writing whole files.
- This code makes mf_rec_cache obsolete (currently only used by ISAM)
One can change info->pos_in_file to a higher value to skip bytes in file if
also info->read_pos is set to info->read_end.
If called through open_cached_file(), then the temporary file will
@@ -65,6 +64,12 @@ static void my_aiowait(my_aio_result *result);
#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
+static int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count);
+static int _my_b_cache_read_r(IO_CACHE *info, uchar *Buffer, size_t Count);
+static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count);
+static int _my_b_cache_write(IO_CACHE *info, const uchar *Buffer, size_t Count);
+static int _my_b_cache_write_r(IO_CACHE *info, const uchar *Buffer, size_t Count);
+
/*
Setup internal pointers inside IO_CACHE
@@ -98,6 +103,8 @@ static void
init_functions(IO_CACHE* info)
{
enum cache_type type= info->type;
+ info->read_function = 0; /* Force a core if used */
+ info->write_function = 0; /* Force a core if used */
switch (type) {
case READ_NET:
/*
@@ -110,11 +117,15 @@ init_functions(IO_CACHE* info)
break;
case SEQ_READ_APPEND:
info->read_function = _my_b_seq_read;
- info->write_function = 0; /* Force a core if used */
break;
- default:
- info->read_function = info->share ? _my_b_read_r : _my_b_read;
- info->write_function = _my_b_write;
+ case READ_CACHE:
+ case WRITE_CACHE:
+ case READ_FIFO:
+ info->read_function = info->share ? _my_b_cache_read_r : _my_b_cache_read;
+ info->write_function = info->share ? _my_b_cache_write_r : _my_b_cache_write;
+ break;
+ case TYPE_NOT_SET:
+ DBUG_ASSERT(0);
}
setup_io_cache(info);
@@ -135,7 +146,7 @@ init_functions(IO_CACHE* info)
type Type of cache
seek_offset Where cache should start reading/writing
use_async_io Set to 1 of we should use async_io (if avaiable)
- cache_myflags Bitmap of differnt flags
+ cache_myflags Bitmap of different flags
MY_WME | MY_FAE | MY_NABP | MY_FNABP |
MY_DONT_CHECK_FILESIZE
@@ -146,7 +157,7 @@ init_functions(IO_CACHE* info)
int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
enum cache_type type, my_off_t seek_offset,
- pbool use_async_io, myf cache_myflags)
+ my_bool use_async_io, myf cache_myflags)
{
size_t min_cache;
my_off_t pos;
@@ -206,7 +217,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
}
}
cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- if (type != READ_NET && type != WRITE_NET)
+ if (type != READ_NET)
{
/* Retry allocating memory in smaller blocks until we get one */
cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
@@ -229,10 +240,11 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if ((info->buffer= (uchar*) my_malloc(buffer_block, flags)) != 0)
{
- info->write_buffer=info->buffer;
if (type == SEQ_READ_APPEND)
- info->write_buffer = info->buffer + cachesize;
- info->alloced_buffer=1;
+ info->write_buffer= info->buffer + cachesize;
+ else
+ info->write_buffer= info->buffer;
+ info->alloced_buffer= 1;
break; /* Enough memory found */
}
if (cachesize == min_cache)
@@ -321,18 +333,16 @@ static void my_aiowait(my_aio_result *result)
my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
my_off_t seek_offset,
- pbool use_async_io __attribute__((unused)),
- pbool clear_cache)
+ my_bool use_async_io __attribute__((unused)),
+ my_bool clear_cache)
{
DBUG_ENTER("reinit_io_cache");
DBUG_PRINT("enter",("cache: 0x%lx type: %d seek_offset: %lu clear_cache: %d",
(ulong) info, type, (ulong) seek_offset,
(int) clear_cache));
- /* One can't do reinit with the following types */
- DBUG_ASSERT(type != READ_NET && info->type != READ_NET &&
- type != WRITE_NET && info->type != WRITE_NET &&
- type != SEQ_READ_APPEND && info->type != SEQ_READ_APPEND);
+ DBUG_ASSERT(type == READ_CACHE || type == WRITE_CACHE);
+ DBUG_ASSERT(info->type == READ_CACHE || info->type == WRITE_CACHE);
/* If the whole file is in memory, avoid flushing to disk */
if (! clear_cache &&
@@ -413,12 +423,72 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
} /* reinit_io_cache */
+int _my_b_read(IO_CACHE *info, uchar *Buffer, size_t Count)
+{
+ size_t left_length;
+ int res;
+
+ /* If the buffer is not empty yet, copy what is available. */
+ if ((left_length= (size_t) (info->read_end - info->read_pos)))
+ {
+ DBUG_ASSERT(Count > left_length);
+ memcpy(Buffer, info->read_pos, left_length);
+ Buffer+=left_length;
+ Count-=left_length;
+ }
+ res= info->read_function(info, Buffer, Count);
+ if (res && info->error >= 0)
+ info->error+= left_length; /* update number or read bytes */
+ return res;
+}
+
+int _my_b_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
+{
+ size_t rest_length;
+ int res;
+
+ /* Always use my_b_flush_io_cache() to flush write_buffer! */
+ DBUG_ASSERT(Buffer != info->write_buffer);
+
+ if (info->pos_in_file + info->buffer_length > info->end_of_file)
+ {
+ my_errno=errno=EFBIG;
+ return info->error = -1;
+ }
+
+ rest_length= (size_t) (info->write_end - info->write_pos);
+ DBUG_ASSERT(Count >= rest_length);
+ memcpy(info->write_pos, Buffer, (size_t) rest_length);
+ Buffer+=rest_length;
+ Count-=rest_length;
+ info->write_pos+=rest_length;
+
+ if (my_b_flush_io_cache(info, 1))
+ return 1;
+
+ if (Count)
+ {
+ my_off_t old_pos_in_file= info->pos_in_file;
+ res= info->write_function(info, Buffer, Count);
+ Count-= info->pos_in_file - old_pos_in_file;
+ Buffer+= info->pos_in_file - old_pos_in_file;
+ }
+ else
+ res= 0;
+
+ if (!res && Count)
+ {
+ memcpy(info->write_pos, Buffer, Count);
+ info->write_pos+= Count;
+ }
+ return res;
+}
/*
Read buffered.
SYNOPSIS
- _my_b_read()
+ _my_b_cache_read()
info IO_CACHE pointer
Buffer Buffer to retrieve count bytes from file
Count Number of bytes to read into Buffer
@@ -434,7 +504,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
types than my_off_t unless you can be sure that their value fits.
Same applies to differences of file offsets.
- When changing this function, check _my_b_read_r(). It might need the
+ When changing this function, check _my_b_cache_read_r(). It might need the
same change.
RETURN
@@ -444,20 +514,11 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
Otherwise info->error contains the number of bytes in Buffer.
*/
-int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
+static int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{
- size_t length,diff_length,left_length, max_length;
+ size_t length, diff_length, left_length= 0, max_length;
my_off_t pos_in_file;
- DBUG_ENTER("_my_b_read");
-
- /* If the buffer is not empty yet, copy what is available. */
- if ((left_length= (size_t) (info->read_end-info->read_pos)))
- {
- DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->read_pos, left_length);
- Buffer+=left_length;
- Count-=left_length;
- }
+ DBUG_ENTER("_my_b_cache_read");
/* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
@@ -513,7 +574,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
what we did already read from a block. That way, the read will
end aligned with a block.
*/
- length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
+ length= IO_ROUND_DN(Count) - diff_length;
if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags))
!= length)
{
@@ -681,12 +742,15 @@ void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
cshare->source_cache= write_cache; /* Can be NULL. */
read_cache->share= cshare;
- read_cache->read_function= _my_b_read_r;
+ read_cache->read_function= _my_b_cache_read_r;
read_cache->current_pos= NULL;
read_cache->current_end= NULL;
if (write_cache)
+ {
write_cache->share= cshare;
+ write_cache->write_function= _my_b_cache_write_r;
+ }
DBUG_VOID_RETURN;
}
@@ -954,7 +1018,7 @@ static void unlock_io_cache(IO_CACHE *cache)
Read from IO_CACHE when it is shared between several threads.
SYNOPSIS
- _my_b_read_r()
+ _my_b_cache_read_r()
cache IO_CACHE pointer
Buffer Buffer to retrieve count bytes from file
Count Number of bytes to read into Buffer
@@ -979,7 +1043,7 @@ static void unlock_io_cache(IO_CACHE *cache)
types than my_off_t unless you can be sure that their value fits.
Same applies to differences of file offsets. (Bug #11527)
- When changing this function, check _my_b_read(). It might need the
+ When changing this function, check _my_b_cache_read(). It might need the
same change.
RETURN
@@ -987,20 +1051,13 @@ static void unlock_io_cache(IO_CACHE *cache)
1 Error: can't read requested characters
*/
-int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
+static int _my_b_cache_read_r(IO_CACHE *cache, uchar *Buffer, size_t Count)
{
my_off_t pos_in_file;
- size_t length, diff_length, left_length;
+ size_t length, diff_length, left_length= 0;
IO_CACHE_SHARE *cshare= cache->share;
- DBUG_ENTER("_my_b_read_r");
+ DBUG_ENTER("_my_b_cache_read_r");
- if ((left_length= (size_t) (cache->read_end - cache->read_pos)))
- {
- DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer, cache->read_pos, left_length);
- Buffer+= left_length;
- Count-= left_length;
- }
while (Count)
{
size_t cnt, len;
@@ -1115,21 +1172,22 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
*/
static void copy_to_read_buffer(IO_CACHE *write_cache,
- const uchar *write_buffer, size_t write_length)
+ const uchar *write_buffer, my_off_t pos_in_file)
{
+ size_t write_length= write_cache->pos_in_file - pos_in_file;
IO_CACHE_SHARE *cshare= write_cache->share;
DBUG_ASSERT(cshare->source_cache == write_cache);
/*
write_length is usually less or equal to buffer_length.
- It can be bigger if _my_b_write() is called with a big length.
+ It can be bigger if _my_b_cache_write_r() is called with a big length.
*/
while (write_length)
{
size_t copy_length= MY_MIN(write_length, write_cache->buffer_length);
int __attribute__((unused)) rc;
- rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+ rc= lock_io_cache(write_cache, pos_in_file);
/* The writing thread does always have the lock when it awakes. */
DBUG_ASSERT(rc);
@@ -1137,7 +1195,7 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
cshare->error= 0;
cshare->read_end= cshare->buffer + copy_length;
- cshare->pos_in_file= write_cache->pos_in_file;
+ cshare->pos_in_file= pos_in_file;
/* Mark all threads as running and wake them. */
unlock_io_cache(write_cache);
@@ -1161,20 +1219,12 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
1 Failed to read
*/
-int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
+static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{
- size_t length, diff_length, left_length, save_count, max_length;
+ size_t length, diff_length, left_length= 0, save_count, max_length;
my_off_t pos_in_file;
save_count=Count;
- /* first, read the regular buffer */
- if ((left_length=(size_t) (info->read_end-info->read_pos)))
- {
- DBUG_ASSERT(Count > left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->read_pos, left_length);
- Buffer+=left_length;
- Count-=left_length;
- }
lock_append_buffer(info);
/* pos_in_file always point on where info->buffer was read */
@@ -1202,7 +1252,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
/* Fill first intern buffer */
size_t read_length;
- length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
+ length= IO_ROUND_DN(Count) - diff_length;
if ((read_length= mysql_file_read(info->file,Buffer, length,
info->myflags)) == (size_t) -1)
{
@@ -1319,18 +1369,14 @@ read_append_buffer:
1 An error has occurred; IO_CACHE to error state.
*/
-int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
+int _my_b_async_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{
- size_t length,read_length,diff_length,left_length,use_length,org_Count;
+ size_t length, read_length, diff_length, left_length=0, use_length, org_Count;
size_t max_length;
my_off_t next_pos_in_file;
uchar *read_buffer;
- memcpy(Buffer,info->read_pos,
- (left_length= (size_t) (info->read_end-info->read_pos)));
- Buffer+=left_length;
org_Count=Count;
- Count-=left_length;
if (info->inited)
{ /* wait for read block */
@@ -1484,7 +1530,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
info->read_end-=info->read_length;
}
info->read_length=info->buffer_length; /* Use hole buffer */
- info->read_function=_my_b_read; /* Use normal IO_READ next */
+ info->read_function=_my_b_cache_read; /* Use normal IO_READ next */
}
else
info->inited=info->aio_result.pending=1;
@@ -1514,70 +1560,60 @@ int _my_b_get(IO_CACHE *info)
-1 On error; my_errno contains error code.
*/
-int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
+static int _my_b_cache_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
{
- size_t rest_length,length;
- my_off_t pos_in_file= info->pos_in_file;
-
- DBUG_EXECUTE_IF("simulate_huge_load_data_file",
- {
- pos_in_file=(my_off_t)(5000000000ULL);
- });
- if (pos_in_file+info->buffer_length > info->end_of_file)
+ if (Buffer != info->write_buffer)
{
- my_errno=errno=EFBIG;
- return info->error = -1;
+ Count= IO_ROUND_DN(Count);
+ if (!Count)
+ return 0;
}
- rest_length= (size_t) (info->write_end - info->write_pos);
- memcpy(info->write_pos,Buffer,(size_t) rest_length);
- Buffer+=rest_length;
- Count-=rest_length;
- info->write_pos+=rest_length;
-
- if (my_b_flush_io_cache(info,1))
- return 1;
- if (Count >= IO_SIZE)
- { /* Fill first intern buffer */
- length=Count & (size_t) ~(IO_SIZE-1);
- if (info->seek_not_done)
+ if (info->seek_not_done)
+ {
+ /*
+ Whenever a function which operates on IO_CACHE flushes/writes
+ some part of the IO_CACHE to disk it will set the property
+ "seek_not_done" to indicate this to other functions operating
+ on the IO_CACHE.
+ */
+ if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET,
+ MYF(info->myflags & MY_WME)) == MY_FILEPOS_ERROR)
{
- /*
- Whenever a function which operates on IO_CACHE flushes/writes
- some part of the IO_CACHE to disk it will set the property
- "seek_not_done" to indicate this to other functions operating
- on the IO_CACHE.
- */
- if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET, MYF(0)))
- {
- info->error= -1;
- return (1);
- }
- info->seek_not_done=0;
+ info->error= -1;
+ return 1;
}
- if (mysql_file_write(info->file, Buffer, length, info->myflags | MY_NABP))
- return info->error= -1;
+ info->seek_not_done=0;
+ }
+ if (mysql_file_write(info->file, Buffer, Count, info->myflags | MY_NABP))
+ return info->error= -1;
- /*
- In case of a shared I/O cache with a writer we normally do direct
- write cache to read cache copy. Simulate this here by direct
- caller buffer to read cache copy. Do it after the write so that
- the cache readers actions on the flushed part can go in parallel
- with the write of the extra stuff. copy_to_read_buffer()
- synchronizes writer and readers so that after this call the
- readers can act on the extra stuff while the writer can go ahead
- and prepare the next output. copy_to_read_buffer() relies on
- info->pos_in_file.
- */
- if (info->share)
- copy_to_read_buffer(info, Buffer, length);
+ info->pos_in_file+= Count;
+ return 0;
+}
+
+
+/*
+ In case of a shared I/O cache with a writer we normally do direct
+ write cache to read cache copy. Simulate this here by direct
+ caller buffer to read cache copy. Do it after the write so that
+ the cache readers actions on the flushed part can go in parallel
+ with the write of the extra stuff. copy_to_read_buffer()
+ synchronizes writer and readers so that after this call the
+ readers can act on the extra stuff while the writer can go ahead
+ and prepare the next output. copy_to_read_buffer() relies on
+ info->pos_in_file.
+*/
+static int _my_b_cache_write_r(IO_CACHE *info, const uchar *Buffer, size_t Count)
+{
+ my_off_t old_pos_in_file= info->pos_in_file;
+ int res= _my_b_cache_write(info, Buffer, Count);
+ if (res)
+ return res;
+
+ DBUG_ASSERT(info->share);
+ copy_to_read_buffer(info, Buffer, old_pos_in_file);
- Count-=length;
- Buffer+=length;
- info->pos_in_file+=length;
- }
- memcpy(info->write_pos,Buffer,(size_t) Count);
- info->write_pos+=Count;
return 0;
}
@@ -1588,7 +1624,7 @@ int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
the write buffer before we are ready with it.
*/
-int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
+int my_b_append(IO_CACHE *info, const uchar *Buffer, size_t Count)
{
size_t rest_length,length;
@@ -1613,7 +1649,7 @@ int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
}
if (Count >= IO_SIZE)
{ /* Fill first intern buffer */
- length=Count & (size_t) ~(IO_SIZE-1);
+ length= IO_ROUND_DN(Count);
if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP))
{
unlock_append_buffer(info);
@@ -1652,7 +1688,7 @@ int my_b_safe_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
we will never get a seek over the end of the buffer
*/
-int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
+int my_block_write(IO_CACHE *info, const uchar *Buffer, size_t Count,
my_off_t pos)
{
size_t length;
@@ -1710,11 +1746,9 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
unlock_append_buffer(info);
-int my_b_flush_io_cache(IO_CACHE *info,
- int need_append_buffer_lock __attribute__((unused)))
+int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
{
size_t length;
- my_off_t pos_in_file;
my_bool append_cache= (info->type == SEQ_READ_APPEND);
DBUG_ENTER("my_b_flush_io_cache");
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
@@ -1733,52 +1767,30 @@ int my_b_flush_io_cache(IO_CACHE *info,
if ((length=(size_t) (info->write_pos - info->write_buffer)))
{
- /*
- In case of a shared I/O cache with a writer we do direct write
- cache to read cache copy. Do it before the write here so that
- the readers can work in parallel with the write.
- copy_to_read_buffer() relies on info->pos_in_file.
- */
- if (info->share)
- copy_to_read_buffer(info, info->write_buffer, length);
-
- pos_in_file=info->pos_in_file;
- /*
- If we have append cache, we always open the file with
- O_APPEND which moves the pos to EOF automatically on every write
- */
- if (!append_cache && info->seek_not_done)
- { /* File touched, do seek */
- if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(info->myflags & MY_WME)) ==
- MY_FILEPOS_ERROR)
- {
- UNLOCK_APPEND_BUFFER;
- DBUG_RETURN((info->error= -1));
- }
- if (!append_cache)
- info->seek_not_done=0;
- }
- if (!append_cache)
- info->pos_in_file+=length;
- info->write_end= (info->write_buffer+info->buffer_length-
- ((pos_in_file+length) & (IO_SIZE-1)));
-
- if (mysql_file_write(info->file,info->write_buffer,length,
- info->myflags | MY_NABP))
- info->error= -1;
- else
- info->error= 0;
- if (!append_cache)
+ info->write_end= (info->write_buffer + info->buffer_length -
+ ((info->pos_in_file + length) & (IO_SIZE - 1)));
+ if (append_cache)
{
- set_if_bigger(info->end_of_file,(pos_in_file+length));
+
+ if (mysql_file_write(info->file, info->write_buffer, length,
+ info->myflags | MY_NABP))
+ info->error= -1;
+ else
+ info->error= 0;
+
+ info->end_of_file+= info->write_pos - info->append_read_pos;
+ info->append_read_pos= info->write_buffer;
+ DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
}
else
{
- info->end_of_file+=(info->write_pos-info->append_read_pos);
- DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
- }
+ int res= info->write_function(info, info->write_buffer, length);
+ if (res)
+ DBUG_RETURN(res);
- info->append_read_pos=info->write_pos=info->write_buffer;
+ set_if_bigger(info->end_of_file, info->pos_in_file);
+ }
+ info->write_pos= info->write_buffer;
++info->disk_writes;
UNLOCK_APPEND_BUFFER;
DBUG_RETURN(info->error);