Commit 196e8529 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent 1841557e
......@@ -285,7 +285,7 @@ enum cache_type
{
TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
SEQ_READ_APPEND /* sequential read or append */,
READ_FIFO, READ_NET,WRITE_NET};
READ_FIFO, READ_NET};
enum flush_type
{
......@@ -517,14 +517,12 @@ extern my_error_reporter my_charset_error_reporter;
#define my_b_read(info,Buffer,Count) \
((info)->read_pos + (Count) <= (info)->read_end ?\
(memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \
((info)->read_pos+=(Count)),0) :\
(*(info)->read_function)((info),Buffer,Count))
((info)->read_pos+=(Count)), 0) : _my_b_read((info), (Buffer), (Count)))
#define my_b_write(info,Buffer,Count) \
((info)->write_pos + (Count) <=(info)->write_end ?\
(memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
((info)->write_pos+=(Count)),0) : \
(*(info)->write_function)((info),(uchar *)(Buffer),(Count)))
((info)->write_pos+=(Count)), 0) : _my_b_write((info), (Buffer), (Count)))
#define my_b_get(info) \
((info)->read_pos != (info)->read_end ?\
......@@ -535,10 +533,7 @@ extern my_error_reporter my_charset_error_reporter;
#define my_b_write_byte(info,chr) \
(((info)->write_pos < (info)->write_end) ?\
((*(info)->write_pos++)=(chr)) :\
(_my_b_write(info,0,0) , ((*(info)->write_pos++)=(chr))))
#define my_b_fill_cache(info) \
(((info)->read_end=(info)->read_pos),(*(info)->read_function)(info,0,0))
((my_b_flush_io_cache(info, 1)), ((*(info)->write_pos++)=(chr))))
#define my_b_tell(info) ((info)->pos_in_file + \
(size_t) (*(info)->current_pos - (info)->request_pos))
......@@ -741,18 +736,15 @@ void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos);
my_off_t my_get_ptr(uchar *ptr, size_t pack_length);
extern 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);
extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
my_off_t seek_offset,pbool use_async_io,
pbool clear_cache);
my_off_t seek_offset, my_bool use_async_io,
my_bool clear_cache);
extern void setup_io_cache(IO_CACHE* info);
extern int _my_b_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_read_r(IO_CACHE *info,uchar *Buffer,size_t Count);
extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
IO_CACHE *write_cache, uint num_threads);
extern void remove_io_thread(IO_CACHE *info);
extern int _my_b_seq_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_net_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_get(IO_CACHE *info);
extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_write(IO_CACHE *info,const uchar *Buffer,size_t Count);
......
......@@ -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];
......
......@@ -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);
......
......@@ -51,7 +51,7 @@
#include "rpl_utility.h"
#include "sql_digest.h"
#define my_b_write_string(A, B) my_b_write((A), (B), (uint) (sizeof(B) - 1))
#define my_b_write_string(A, B) my_b_write((A), (uchar*)(B), (uint) (sizeof(B) - 1))
using std::max;
......@@ -353,13 +353,13 @@ static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
{
char c;
switch ((c=*str++)) {
case '\n': my_b_write(cache, "\\n", 2); break;
case '\r': my_b_write(cache, "\\r", 2); break;
case '\\': my_b_write(cache, "\\\\", 2); break;
case '\b': my_b_write(cache, "\\b", 2); break;
case '\t': my_b_write(cache, "\\t", 2); break;
case '\'': my_b_write(cache, "\\'", 2); break;
case 0 : my_b_write(cache, "\\0", 2); break;
case '\n': my_b_write(cache, (uchar*)"\\n", 2); break;
case '\r': my_b_write(cache, (uchar*)"\\r", 2); break;
case '\\': my_b_write(cache, (uchar*)"\\\\", 2); break;
case '\b': my_b_write(cache, (uchar*)"\\b", 2); break;
case '\t': my_b_write(cache, (uchar*)"\\t", 2); break;
case '\'': my_b_write(cache, (uchar*)"\\'", 2); break;
case 0 : my_b_write(cache, (uchar*)"\\0", 2); break;
default:
my_b_write_byte(cache, c);
break;
......@@ -755,7 +755,7 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
if (bits_changed & option)
{
if (*need_comma)
my_b_write(file, ", ", 2);
my_b_write(file, (uchar*)", ", 2);
my_b_printf(file, "%s=%d", name, MY_TEST(flags & option));
*need_comma= 1;
}
......@@ -1797,7 +1797,7 @@ static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf));
my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written);
my_b_write(file, "#\n", 2);
my_b_write(file, (uchar*)"#\n", 2);
}
......@@ -1913,7 +1913,7 @@ static void hexdump_data_to_io_cache(IO_CACHE *file,
my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
c - emit_buffer);
}
my_b_write(file, "#\n", 2);
my_b_write(file, (uchar*)"#\n", 2);
}
/*
......@@ -1970,7 +1970,7 @@ void Log_event::print_header(IO_CACHE* file,
Prefix the next line so that the output from print_helper()
will appear as a comment.
*/
my_b_write(file, "# Event: ", 9);
my_b_write(file, (uchar*)"# Event: ", 9);
}
DBUG_VOID_RETURN;
}
......@@ -1996,9 +1996,9 @@ my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
if (*s > 0x1F)
my_b_write_byte(file, *s);
else if (*s == '\'')
my_b_write(file, "\\'", 2);
my_b_write(file, (uchar*)"\\'", 2);
else if (*s == '\\')
my_b_write(file, "\\\\", 2);
my_b_write(file, (uchar*)"\\\\", 2);
else
{
uchar hex[10];
......@@ -2021,7 +2021,7 @@ static void
my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
{
uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
my_b_write(file, "b'", 2);
my_b_write(file, (uchar*)"b'", 2);
for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
{
int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
......@@ -2158,7 +2158,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
size_t length;
longlong si= sint8korr(ptr);
length= (longlong10_to_str(si, tmp, -10) - tmp);
my_b_write(file, tmp, length);
my_b_write(file, (uchar*)tmp, length);
if (si < 0)
{
ulonglong ui= uint8korr(ptr);
......@@ -2187,7 +2187,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
pos+= sprintf(pos, "%09d.", dec.buf[i]);
pos+= sprintf(pos, "%09d", dec.buf[i]);
length= (uint) (pos - buff);
my_b_write(file, buff, length);
my_b_write(file, (uchar*)buff, length);
my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
precision, decimals);
return bin_size;
......@@ -2239,7 +2239,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
struct timeval tm;
my_timestamp_from_binary(&tm, ptr, meta);
int buflen= my_timeval_to_str(&tm, buf, meta);
my_b_write(file, buf, buflen);
my_b_write(file, (uchar*)buf, buflen);
my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
return my_timestamp_binary_length(meta);
}
......@@ -2477,7 +2477,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
if (print_event_info->verbose > 1)
{
my_b_write(file, " /* ", 4);
my_b_write(file, (uchar*)" /* ", 4);
if (typestr[0])
my_b_printf(file, "%s ", typestr);
......@@ -2487,7 +2487,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
td->field_metadata(i),
td->maybe_null(i), is_null);
my_b_write(file, "*/", 2);
my_b_write(file, (uchar*)"*/", 2);
}
my_b_write_byte(file, '\n');
......
......@@ -294,7 +294,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
if (my_b_append(&file, (const uchar *)STRING_WITH_LEN("TYPE=")) ||
my_b_append(&file, (const uchar *)type->str, type->length) ||
my_b_append(&file, (const uchar *)STRING_WITH_LEN("\n")))
goto err_w_file;
goto err_w_cache;
// write parameters to temporary file
for (param= parameters; param->name.str; param++)
......
......@@ -42,6 +42,8 @@
#include "sql_derived.h"
#include "sql_show.h"
extern "C" int _my_b_net_read(IO_CACHE *info, uchar *Buffer, size_t Count);
class XML_TAG {
public:
int level;
......
......@@ -53,7 +53,7 @@ int unique_write_to_file(uchar* key, element_count count, Unique *unique)
int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique)
{
return my_b_write(&unique->file, key, unique->size) ||
my_b_write(&unique->file, &count, sizeof(element_count)) ? 1 : 0;
my_b_write(&unique->file, (uchar*)&count, sizeof(element_count)) ? 1 : 0;
}
int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
......@@ -694,7 +694,6 @@ bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge)
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
MYF(MY_WME))))
return 1;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
Sort_param sort_param;
bzero((char*) &sort_param,sizeof(sort_param));
......
......@@ -458,7 +458,7 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf,
goto cleanup2;
}
if (ev->write(&cache) || my_b_write(&cache, rbr_buf, buf_len) ||
if (ev->write(&cache) || my_b_write(&cache, (uchar*)rbr_buf, buf_len) ||
flush_io_cache(&cache))
{
WSREP_ERROR("Failed to write to '%s'.", filename);
......
......@@ -81,7 +81,7 @@ my_bool _ma_read_cache(MARIA_HA *handler, IO_CACHE *info, uchar *buff,
}
else
info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
if (!_my_b_read(info,buff,length))
DBUG_RETURN(0);
read_length=info->error;
}
......
......@@ -4021,8 +4021,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
share->state.state.data_file_length=sort_param.max_pos;
param->read_cache.file= info->dfile.file; /* re-init read cache */
reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length,
1,1);
if (share->data_file_type != BLOCK_RECORD)
reinit_io_cache(&param->read_cache, READ_CACHE,
share->pack.header_length, 1, 1);
}
if (param->testflag & T_WRITE_LOOP)
......
......@@ -82,7 +82,7 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
}
else
info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length))
if (!_my_b_read(info,buff,length))
DBUG_RETURN(0);
read_length=info->error;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment