diff options
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/Makefile.am | 1 | ||||
-rw-r--r-- | myisam/mi_extra.c | 3 | ||||
-rw-r--r-- | myisam/mi_preload.c | 118 | ||||
-rw-r--r-- | myisam/myisamdef.h | 1 |
4 files changed, 123 insertions, 0 deletions
diff --git a/myisam/Makefile.am b/myisam/Makefile.am index f8225868d96..d4cd953ac66 100644 --- a/myisam/Makefile.am +++ b/myisam/Makefile.am @@ -47,6 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ mi_range.c mi_dbug.c mi_checksum.c mi_log.c \ mi_changed.c mi_static.c mi_delete_all.c \ mi_delete_table.c mi_rename.c mi_check.c \ + mi_preload.c \ ft_parser.c ft_stopwords.c ft_static.c \ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \ rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 75057dd4e6a..4b71f3a867b 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -367,6 +367,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) if (!share->state.header.uniques) info->opt_flag|= OPT_NO_ROWS; break; + case HA_EXTRA_PRELOAD_BUFFER_SIZE: + info->preload_buff_size= *((ulong *) extra_arg); + break; case HA_EXTRA_KEY_CACHE: case HA_EXTRA_NO_KEY_CACHE: default: diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c new file mode 100644 index 00000000000..be45be66ecf --- /dev/null +++ b/myisam/mi_preload.c @@ -0,0 +1,118 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Preload indexes into key cache +*/ + +#include "myisamdef.h" + + +/* + Preload pages of the index file for a table into the key cache + + SYNOPSIS + mi_preload() + info open table + map map of indexes to preload into key cache + ignore_leaves only non-leaves pages are to be preloaded + + RETURN VALUE + 0 if a success. error code - otherwise. + + NOTES. + At present pages for all indexes are preloaded. + In future only pages for indexes specified in the key_map parameter + of the table will be preloaded. +*/ + +int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) +{ + uint i; + uint length; + uint block_length= 0; + uchar *buff= NULL; + MYISAM_SHARE* share= info->s; + uint keys= share->state.header.keys; + MI_KEYDEF *keyinfo= share->keyinfo; + my_off_t key_file_length= share->state.state.key_file_length; + my_off_t pos= share->base.keystart; + + if (!keys || !key_map || key_file_length == pos) + return 0; + + block_length= keyinfo[0].block_length; + + if (!key_map) + return 0; + + /* Check whether all indexes use the same block size */ + for (i= 1 ; i < keys ; i++) + { + if (keyinfo[i].block_length != block_length) + return (my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); + } + + length= info->preload_buff_size/block_length * block_length; + set_if_bigger(length, block_length); + + if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) + return (my_errno= HA_ERR_OUT_OF_MEM); + + if (flush_key_blocks(share->kfile, FLUSH_RELEASE)) + goto err; + + do + { + /* Read the next block of index file into the preload buffer */ + set_if_smaller(length, key_file_length-pos); + if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE))) + goto err; + + if (ignore_leaves) + { + uchar *end= buff+length; + do + { + if (mi_test_if_nod(buff)) + { + if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length)) + goto err; + } + pos+= block_length; + } + while ((buff+= block_length) != end); + buff= end-length; + } + else + { + if (key_cache_insert(share->kfile, pos, (byte*) buff, length)) + goto err; + pos+= length; + } + + } + while (pos != key_file_length); + + my_free(buff, MYF(0)); + + return 0; + +err: + my_free(buff, MYF(MY_ALLOW_ZERO_PTR)); + return (my_errno= errno); +} + diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 50320f1ecbd..9321a3918e2 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -262,6 +262,7 @@ struct st_myisam_info { int save_lastinx; LIST open_list; IO_CACHE rec_cache; /* When cacheing records */ + uint preload_buff_size; /* When preloading indexes */ myf lock_wait; /* is 0 or MY_DONT_WAIT */ my_bool was_locked; /* Was locked in panic */ my_bool quick_mode; |