2 Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 Preload indexes into key cache
22 #include "myisamdef.h"
26 Preload pages of the index file for a table into the key cache
31 map map of indexes to preload into key cache
32 ignore_leaves only non-leaves pages are to be preloaded
35 0 if a success. error code - otherwise.
38 At present pages for all indexes are preloaded.
39 In future only pages for indexes specified in the key_map parameter
40 of the table will be preloaded.
43 int mi_preload(MI_INFO
*info
, ulonglong key_map
, my_bool ignore_leaves
)
46 ulong length
, block_length
= 0;
48 MYISAM_SHARE
* share
= info
->s
;
49 uint keys
= share
->state
.header
.keys
;
50 MI_KEYDEF
*keyinfo
= share
->keyinfo
;
51 my_off_t key_file_length
= share
->state
.state
.key_file_length
;
52 my_off_t pos
= share
->base
.keystart
;
53 DBUG_ENTER("mi_preload");
55 if (!keys
|| !mi_is_any_key_active(key_map
) || key_file_length
== pos
)
58 /* Preload into a non initialized key cache should never happen. */
59 DBUG_ASSERT(share
->key_cache
->key_cache_inited
);
61 block_length
= keyinfo
[0].block_length
;
65 /* Check whether all indexes use the same block size */
66 for (i
= 1 ; i
< keys
; i
++)
68 if (keyinfo
[i
].block_length
!= block_length
)
69 DBUG_RETURN(my_errno
= HA_ERR_NON_UNIQUE_BLOCK_SIZE
);
73 block_length
= share
->key_cache
->key_cache_block_size
;
75 length
= info
->preload_buff_size
/block_length
* block_length
;
76 set_if_bigger(length
, block_length
);
78 if (!(buff
= (uchar
*) my_malloc(length
, MYF(MY_WME
))))
79 DBUG_RETURN(my_errno
= HA_ERR_OUT_OF_MEM
);
81 if (flush_key_blocks(share
->key_cache
,share
->kfile
, FLUSH_RELEASE
))
86 /* Read the next block of index file into the preload buffer */
87 if ((my_off_t
) length
> (key_file_length
-pos
))
88 length
= (ulong
) (key_file_length
-pos
);
89 if (my_pread(share
->kfile
, (uchar
*) buff
, length
, pos
, MYF(MY_FAE
|MY_FNABP
)))
94 uchar
*end
= buff
+length
;
97 if (mi_test_if_nod(buff
))
99 if (key_cache_insert(share
->key_cache
,
100 share
->kfile
, pos
, DFLT_INIT_HITS
,
101 (uchar
*) buff
, block_length
))
106 while ((buff
+= block_length
) != end
);
111 if (key_cache_insert(share
->key_cache
,
112 share
->kfile
, pos
, DFLT_INIT_HITS
,
113 (uchar
*) buff
, length
))
118 while (pos
!= key_file_length
);
120 my_free((char*) buff
, MYF(0));
124 my_free((char*) buff
, MYF(MY_ALLOW_ZERO_PTR
));
125 DBUG_RETURN(my_errno
= errno
);