1
by brian
clean slate |
1 |
/* Copyright (C) 2003, 2005 MySQL AB
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
14 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
16 |
/*
|
|
17 |
Preload indexes into key cache
|
|
18 |
*/
|
|
19 |
||
20 |
#include "myisamdef.h" |
|
21 |
||
22 |
||
23 |
/*
|
|
24 |
Preload pages of the index file for a table into the key cache
|
|
25 |
||
26 |
SYNOPSIS
|
|
27 |
mi_preload()
|
|
28 |
info open table
|
|
29 |
map map of indexes to preload into key cache
|
|
30 |
ignore_leaves only non-leaves pages are to be preloaded
|
|
31 |
||
32 |
RETURN VALUE
|
|
33 |
0 if a success. error code - otherwise.
|
|
34 |
||
35 |
NOTES.
|
|
36 |
At present pages for all indexes are preloaded.
|
|
37 |
In future only pages for indexes specified in the key_map parameter
|
|
38 |
of the table will be preloaded.
|
|
39 |
*/
|
|
40 |
||
41 |
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) |
|
42 |
{
|
|
43 |
uint i; |
|
44 |
ulong length, block_length= 0; |
|
45 |
uchar *buff= NULL; |
|
46 |
MYISAM_SHARE* share= info->s; |
|
47 |
uint keys= share->state.header.keys; |
|
48 |
MI_KEYDEF *keyinfo= share->keyinfo; |
|
49 |
my_off_t key_file_length= share->state.state.key_file_length; |
|
50 |
my_off_t pos= share->base.keystart; |
|
51 |
DBUG_ENTER("mi_preload"); |
|
52 |
||
53 |
if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos) |
|
54 |
DBUG_RETURN(0); |
|
55 |
||
56 |
block_length= keyinfo[0].block_length; |
|
57 |
||
58 |
if (ignore_leaves) |
|
59 |
{
|
|
60 |
/* Check whether all indexes use the same block size */
|
|
61 |
for (i= 1 ; i < keys ; i++) |
|
62 |
{
|
|
63 |
if (keyinfo[i].block_length != block_length) |
|
64 |
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); |
|
65 |
}
|
|
66 |
}
|
|
67 |
else
|
|
68 |
block_length= share->key_cache->key_cache_block_size; |
|
69 |
||
70 |
length= info->preload_buff_size/block_length * block_length; |
|
71 |
set_if_bigger(length, block_length); |
|
72 |
||
73 |
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) |
|
74 |
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM); |
|
75 |
||
76 |
if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_RELEASE)) |
|
77 |
goto err; |
|
78 |
||
79 |
do
|
|
80 |
{
|
|
81 |
/* Read the next block of index file into the preload buffer */
|
|
82 |
if ((my_off_t) length > (key_file_length-pos)) |
|
83 |
length= (ulong) (key_file_length-pos); |
|
84 |
if (my_pread(share->kfile, (uchar*) buff, length, pos, MYF(MY_FAE|MY_FNABP))) |
|
85 |
goto err; |
|
86 |
||
87 |
if (ignore_leaves) |
|
88 |
{
|
|
89 |
uchar *end= buff+length; |
|
90 |
do
|
|
91 |
{
|
|
92 |
if (mi_test_if_nod(buff)) |
|
93 |
{
|
|
94 |
if (key_cache_insert(share->key_cache, |
|
95 |
share->kfile, pos, DFLT_INIT_HITS, |
|
96 |
(uchar*) buff, block_length)) |
|
97 |
goto err; |
|
98 |
}
|
|
99 |
pos+= block_length; |
|
100 |
}
|
|
101 |
while ((buff+= block_length) != end); |
|
102 |
buff= end-length; |
|
103 |
}
|
|
104 |
else
|
|
105 |
{
|
|
106 |
if (key_cache_insert(share->key_cache, |
|
107 |
share->kfile, pos, DFLT_INIT_HITS, |
|
108 |
(uchar*) buff, length)) |
|
109 |
goto err; |
|
110 |
pos+= length; |
|
111 |
}
|
|
112 |
}
|
|
113 |
while (pos != key_file_length); |
|
114 |
||
115 |
my_free((char*) buff, MYF(0)); |
|
116 |
DBUG_RETURN(0); |
|
117 |
||
118 |
err: |
|
119 |
my_free((char*) buff, MYF(MY_ALLOW_ZERO_PTR)); |
|
120 |
DBUG_RETURN(my_errno= errno); |
|
121 |
}
|
|
122 |