summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
Diffstat (limited to 'myisam')
-rw-r--r--myisam/Makefile.am1
-rw-r--r--myisam/mi_extra.c3
-rw-r--r--myisam/mi_preload.c118
-rw-r--r--myisam/myisamdef.h1
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;