diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-05-18 11:54:55 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-06-02 18:53:37 +0200 |
commit | 196e8529837558a72baf31d012285cc283b8e95d (patch) | |
tree | 75feb69d20c5fb5944dd6195bf00440143497232 | |
parent | 1841557e407038e3611b0788eaf70fd3d8eb043e (diff) | |
download | mariadb-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
-rw-r--r-- | include/my_sys.h | 22 | ||||
-rw-r--r-- | mysys/mf_cache.c | 32 | ||||
-rw-r--r-- | mysys/mf_iocache.c | 352 | ||||
-rw-r--r-- | sql/log_event.cc | 40 | ||||
-rw-r--r-- | sql/parse_file.cc | 2 | ||||
-rw-r--r-- | sql/sql_load.cc | 2 | ||||
-rw-r--r-- | sql/uniques.cc | 3 | ||||
-rw-r--r-- | sql/wsrep_binlog.cc | 2 | ||||
-rw-r--r-- | storage/maria/ma_cache.c | 2 | ||||
-rw-r--r-- | storage/maria/ma_check.c | 5 | ||||
-rw-r--r-- | storage/myisam/mi_cache.c | 2 |
11 files changed, 236 insertions, 228 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index 17ad872e4e9..3d930d31bc2 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -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); 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); diff --git a/sql/log_event.cc b/sql/log_event.cc index 8a4ffd804ee..95438b69348 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -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'); diff --git a/sql/parse_file.cc b/sql/parse_file.cc index df0215fb167..14c32eb09c6 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -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++) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 62b6e1742f1..142036b2191 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -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; diff --git a/sql/uniques.cc b/sql/uniques.cc index c755293035b..63eb6e0eb90 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -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)); diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index f37d9e0fbc9..b71da709eda 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -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); diff --git a/storage/maria/ma_cache.c b/storage/maria/ma_cache.c index 35926d37e03..e32ba73f0a5 100644 --- a/storage/maria/ma_cache.c +++ b/storage/maria/ma_cache.c @@ -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; } diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 644813ce85c..506ce2307a3 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -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(¶m->read_cache,READ_CACHE,share->pack.header_length, - 1,1); + if (share->data_file_type != BLOCK_RECORD) + reinit_io_cache(¶m->read_cache, READ_CACHE, + share->pack.header_length, 1, 1); } if (param->testflag & T_WRITE_LOOP) diff --git a/storage/myisam/mi_cache.c b/storage/myisam/mi_cache.c index 3477e67eae5..d86dcb4d918 100644 --- a/storage/myisam/mi_cache.c +++ b/storage/myisam/mi_cache.c @@ -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; } |