diff options
Diffstat (limited to 'myisam/mi_cache.c')
-rw-r--r-- | myisam/mi_cache.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/myisam/mi_cache.c b/myisam/mi_cache.c index 55f85fb99d1..bd3c4cd213c 100644 --- a/myisam/mi_cache.c +++ b/myisam/mi_cache.c @@ -14,14 +14,26 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Functions for read record cacheing with myisam */ -/* Used instead of my_b_read() to allow for no-cacheed seeks */ +/* + Functions for read record cacheing with myisam + Used for reading dynamic/compressed records from datafile. -#include "myisamdef.h" + Can fetch data directly from file (outside cache), + if reading a small chunk straight before the cached part (with possible + overlap). + + Can be explicitly asked not to use cache (by not setting READING_NEXT in + flag) - useful for occasional out-of-cache reads, when the next read is + expected to hit the cache again. + + Allows "partial read" errors in the record header (when READING_HEADER flag + is set) - unread part is bzero'ed + + Note: out-of-cache reads are disabled for shared IO_CACHE's +*/ - /* Copy block from cache if it`s in it. If re_read_if_possibly is */ - /* set read to cache (if after current file-position) else read to */ - /* buff */ + +#include "myisamdef.h" int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, int flag) @@ -31,7 +43,7 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, char *in_buff_pos; DBUG_ENTER("_mi_read_cache"); - if (pos < info->pos_in_file) + if (pos < info->pos_in_file && ! info->share) { read_length=length; if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos)) @@ -44,7 +56,8 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, pos+=read_length; buff+=read_length; } - if ((offset= (my_off_t) (pos - info->pos_in_file)) < + if (pos >= info->pos_in_file && + (offset= (my_off_t) (pos - info->pos_in_file)) < (my_off_t) (info->read_end - info->request_pos)) { in_buff_pos=info->request_pos+(uint) offset; @@ -57,10 +70,10 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, } else in_buff_length=0; - if (flag & READING_NEXT) + if (flag & READING_NEXT || info->share) { - if (pos != ((info)->pos_in_file + - (uint) ((info)->read_end - (info)->request_pos))) + if (pos != + (info->pos_in_file + (uint) (info->read_end - info->request_pos))) { info->pos_in_file=pos; /* Force start here */ info->read_pos=info->read_end=info->request_pos; /* Everything used */ @@ -70,34 +83,25 @@ int _mi_read_cache(IO_CACHE *info, byte *buff, my_off_t pos, uint length, info->read_pos=info->read_end; /* All block used */ if (!(*info->read_function)(info,buff,length)) DBUG_RETURN(0); - if (!(flag & READING_HEADER) || info->error == -1 || - (uint) info->error+in_buff_length < 3) - { - DBUG_PRINT("error", - ("Error %d reading next-multi-part block (Got %d bytes)", - my_errno, info->error)); - if (!my_errno || my_errno == -1) - my_errno=HA_ERR_WRONG_IN_RECORD; - DBUG_RETURN(1); - } - bzero(buff+info->error,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - - (uint) info->error); - DBUG_RETURN(0); + read_length=info->error; + } + else + { + info->seek_not_done=1; + if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length) + DBUG_RETURN(0); } - info->seek_not_done=1; - if ((read_length=my_pread(info->file,buff,length,pos,MYF(0))) == length) - DBUG_RETURN(0); if (!(flag & READING_HEADER) || (int) read_length == -1 || read_length+in_buff_length < 3) { DBUG_PRINT("error", - ("Error %d reading new block (Got %d bytes)", - my_errno, (int) read_length)); + ("Error %d reading next-multi-part block (Got %d bytes)", + my_errno, (int) read_length)); if (!my_errno || my_errno == -1) my_errno=HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(1); } bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - - read_length); + read_length); DBUG_RETURN(0); } /* _mi_read_cache */ |